gfx/skia/trunk/src/utils/SkLua.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2013 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #include "SkLua.h"
michael@0 9
michael@0 10 #if SK_SUPPORT_GPU
michael@0 11 #include "GrReducedClip.h"
michael@0 12 #endif
michael@0 13
michael@0 14 #include "SkCanvas.h"
michael@0 15 #include "SkData.h"
michael@0 16 #include "SkDocument.h"
michael@0 17 #include "SkImage.h"
michael@0 18 #include "SkMatrix.h"
michael@0 19 #include "SkPaint.h"
michael@0 20 #include "SkPath.h"
michael@0 21 #include "SkPixelRef.h"
michael@0 22 #include "SkRRect.h"
michael@0 23 #include "SkString.h"
michael@0 24 #include "SkTypeface.h"
michael@0 25
michael@0 26 extern "C" {
michael@0 27 #include "lua.h"
michael@0 28 #include "lualib.h"
michael@0 29 #include "lauxlib.h"
michael@0 30 }
michael@0 31
michael@0 32 // return the metatable name for a given class
michael@0 33 template <typename T> const char* get_mtname();
michael@0 34 #define DEF_MTNAME(T) \
michael@0 35 template <> const char* get_mtname<T>() { \
michael@0 36 return #T "_LuaMetaTableName"; \
michael@0 37 }
michael@0 38
michael@0 39 DEF_MTNAME(SkCanvas)
michael@0 40 DEF_MTNAME(SkDocument)
michael@0 41 DEF_MTNAME(SkImage)
michael@0 42 DEF_MTNAME(SkMatrix)
michael@0 43 DEF_MTNAME(SkRRect)
michael@0 44 DEF_MTNAME(SkPath)
michael@0 45 DEF_MTNAME(SkPaint)
michael@0 46 DEF_MTNAME(SkShader)
michael@0 47 DEF_MTNAME(SkTypeface)
michael@0 48
michael@0 49 template <typename T> T* push_new(lua_State* L) {
michael@0 50 T* addr = (T*)lua_newuserdata(L, sizeof(T));
michael@0 51 new (addr) T;
michael@0 52 luaL_getmetatable(L, get_mtname<T>());
michael@0 53 lua_setmetatable(L, -2);
michael@0 54 return addr;
michael@0 55 }
michael@0 56
michael@0 57 template <typename T> void push_obj(lua_State* L, const T& obj) {
michael@0 58 new (lua_newuserdata(L, sizeof(T))) T(obj);
michael@0 59 luaL_getmetatable(L, get_mtname<T>());
michael@0 60 lua_setmetatable(L, -2);
michael@0 61 }
michael@0 62
michael@0 63 template <typename T> void push_ref(lua_State* L, T* ref) {
michael@0 64 *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
michael@0 65 luaL_getmetatable(L, get_mtname<T>());
michael@0 66 lua_setmetatable(L, -2);
michael@0 67 }
michael@0 68
michael@0 69 template <typename T> T* get_ref(lua_State* L, int index) {
michael@0 70 return *(T**)luaL_checkudata(L, index, get_mtname<T>());
michael@0 71 }
michael@0 72
michael@0 73 template <typename T> T* get_obj(lua_State* L, int index) {
michael@0 74 return (T*)luaL_checkudata(L, index, get_mtname<T>());
michael@0 75 }
michael@0 76
michael@0 77 static bool lua2bool(lua_State* L, int index) {
michael@0 78 return !!lua_toboolean(L, index);
michael@0 79 }
michael@0 80
michael@0 81 ///////////////////////////////////////////////////////////////////////////////
michael@0 82
michael@0 83 SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) {
michael@0 84 fL = luaL_newstate();
michael@0 85 luaL_openlibs(fL);
michael@0 86 SkLua::Load(fL);
michael@0 87 }
michael@0 88
michael@0 89 SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {}
michael@0 90
michael@0 91 SkLua::~SkLua() {
michael@0 92 if (fWeOwnL) {
michael@0 93 if (fTermCode.size() > 0) {
michael@0 94 lua_getglobal(fL, fTermCode.c_str());
michael@0 95 if (lua_pcall(fL, 0, 0, 0) != LUA_OK) {
michael@0 96 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
michael@0 97 }
michael@0 98 }
michael@0 99 lua_close(fL);
michael@0 100 }
michael@0 101 }
michael@0 102
michael@0 103 bool SkLua::runCode(const char code[]) {
michael@0 104 int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0);
michael@0 105 if (err) {
michael@0 106 SkDebugf("--- lua failed: %s\n", lua_tostring(fL, -1));
michael@0 107 return false;
michael@0 108 }
michael@0 109 return true;
michael@0 110 }
michael@0 111
michael@0 112 bool SkLua::runCode(const void* code, size_t size) {
michael@0 113 SkString str((const char*)code, size);
michael@0 114 return this->runCode(str.c_str());
michael@0 115 }
michael@0 116
michael@0 117 ///////////////////////////////////////////////////////////////////////////////
michael@0 118
michael@0 119 #define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0)
michael@0 120
michael@0 121 static void setfield_bool_if(lua_State* L, const char key[], bool pred) {
michael@0 122 if (pred) {
michael@0 123 lua_pushboolean(L, true);
michael@0 124 lua_setfield(L, -2, key);
michael@0 125 }
michael@0 126 }
michael@0 127
michael@0 128 static void setfield_string(lua_State* L, const char key[], const char value[]) {
michael@0 129 lua_pushstring(L, value);
michael@0 130 lua_setfield(L, -2, key);
michael@0 131 }
michael@0 132
michael@0 133 static void setfield_number(lua_State* L, const char key[], double value) {
michael@0 134 lua_pushnumber(L, value);
michael@0 135 lua_setfield(L, -2, key);
michael@0 136 }
michael@0 137
michael@0 138 static void setfield_boolean(lua_State* L, const char key[], bool value) {
michael@0 139 lua_pushboolean(L, value);
michael@0 140 lua_setfield(L, -2, key);
michael@0 141 }
michael@0 142
michael@0 143 static void setfield_scalar(lua_State* L, const char key[], SkScalar value) {
michael@0 144 setfield_number(L, key, SkScalarToLua(value));
michael@0 145 }
michael@0 146
michael@0 147 static void setfield_function(lua_State* L,
michael@0 148 const char key[], lua_CFunction value) {
michael@0 149 lua_pushcfunction(L, value);
michael@0 150 lua_setfield(L, -2, key);
michael@0 151 }
michael@0 152
michael@0 153 static void setarray_number(lua_State* L, int index, double value) {
michael@0 154 lua_pushnumber(L, value);
michael@0 155 lua_rawseti(L, -2, index);
michael@0 156 }
michael@0 157
michael@0 158 void SkLua::pushBool(bool value, const char key[]) {
michael@0 159 lua_pushboolean(fL, value);
michael@0 160 CHECK_SETFIELD(key);
michael@0 161 }
michael@0 162
michael@0 163 void SkLua::pushString(const char str[], const char key[]) {
michael@0 164 lua_pushstring(fL, str);
michael@0 165 CHECK_SETFIELD(key);
michael@0 166 }
michael@0 167
michael@0 168 void SkLua::pushString(const char str[], size_t length, const char key[]) {
michael@0 169 // TODO: how to do this w/o making a copy?
michael@0 170 SkString s(str, length);
michael@0 171 lua_pushstring(fL, s.c_str());
michael@0 172 CHECK_SETFIELD(key);
michael@0 173 }
michael@0 174
michael@0 175 void SkLua::pushString(const SkString& str, const char key[]) {
michael@0 176 lua_pushstring(fL, str.c_str());
michael@0 177 CHECK_SETFIELD(key);
michael@0 178 }
michael@0 179
michael@0 180 void SkLua::pushColor(SkColor color, const char key[]) {
michael@0 181 lua_newtable(fL);
michael@0 182 setfield_number(fL, "a", SkColorGetA(color) / 255.0);
michael@0 183 setfield_number(fL, "r", SkColorGetR(color) / 255.0);
michael@0 184 setfield_number(fL, "g", SkColorGetG(color) / 255.0);
michael@0 185 setfield_number(fL, "b", SkColorGetB(color) / 255.0);
michael@0 186 CHECK_SETFIELD(key);
michael@0 187 }
michael@0 188
michael@0 189 void SkLua::pushU32(uint32_t value, const char key[]) {
michael@0 190 lua_pushnumber(fL, (double)value);
michael@0 191 CHECK_SETFIELD(key);
michael@0 192 }
michael@0 193
michael@0 194 void SkLua::pushScalar(SkScalar value, const char key[]) {
michael@0 195 lua_pushnumber(fL, SkScalarToLua(value));
michael@0 196 CHECK_SETFIELD(key);
michael@0 197 }
michael@0 198
michael@0 199 void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
michael@0 200 lua_newtable(fL);
michael@0 201 for (int i = 0; i < count; ++i) {
michael@0 202 // make it base-1 to match lua convention
michael@0 203 setarray_number(fL, i + 1, (double)array[i]);
michael@0 204 }
michael@0 205 CHECK_SETFIELD(key);
michael@0 206 }
michael@0 207
michael@0 208 void SkLua::pushRect(const SkRect& r, const char key[]) {
michael@0 209 lua_newtable(fL);
michael@0 210 setfield_scalar(fL, "left", r.fLeft);
michael@0 211 setfield_scalar(fL, "top", r.fTop);
michael@0 212 setfield_scalar(fL, "right", r.fRight);
michael@0 213 setfield_scalar(fL, "bottom", r.fBottom);
michael@0 214 CHECK_SETFIELD(key);
michael@0 215 }
michael@0 216
michael@0 217 void SkLua::pushRRect(const SkRRect& rr, const char key[]) {
michael@0 218 push_obj(fL, rr);
michael@0 219 CHECK_SETFIELD(key);
michael@0 220 }
michael@0 221
michael@0 222 void SkLua::pushMatrix(const SkMatrix& matrix, const char key[]) {
michael@0 223 push_obj(fL, matrix);
michael@0 224 CHECK_SETFIELD(key);
michael@0 225 }
michael@0 226
michael@0 227 void SkLua::pushPaint(const SkPaint& paint, const char key[]) {
michael@0 228 push_obj(fL, paint);
michael@0 229 CHECK_SETFIELD(key);
michael@0 230 }
michael@0 231
michael@0 232 void SkLua::pushPath(const SkPath& path, const char key[]) {
michael@0 233 push_obj(fL, path);
michael@0 234 CHECK_SETFIELD(key);
michael@0 235 }
michael@0 236
michael@0 237 void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
michael@0 238 push_ref(fL, canvas);
michael@0 239 CHECK_SETFIELD(key);
michael@0 240 }
michael@0 241
michael@0 242 static const char* element_type(SkClipStack::Element::Type type) {
michael@0 243 switch (type) {
michael@0 244 case SkClipStack::Element::kEmpty_Type:
michael@0 245 return "empty";
michael@0 246 case SkClipStack::Element::kRect_Type:
michael@0 247 return "rect";
michael@0 248 case SkClipStack::Element::kRRect_Type:
michael@0 249 return "rrect";
michael@0 250 case SkClipStack::Element::kPath_Type:
michael@0 251 return "path";
michael@0 252 }
michael@0 253 return "unknown";
michael@0 254 }
michael@0 255
michael@0 256 static const char* region_op(SkRegion::Op op) {
michael@0 257 switch (op) {
michael@0 258 case SkRegion::kDifference_Op:
michael@0 259 return "difference";
michael@0 260 case SkRegion::kIntersect_Op:
michael@0 261 return "intersect";
michael@0 262 case SkRegion::kUnion_Op:
michael@0 263 return "union";
michael@0 264 case SkRegion::kXOR_Op:
michael@0 265 return "xor";
michael@0 266 case SkRegion::kReverseDifference_Op:
michael@0 267 return "reverse-difference";
michael@0 268 case SkRegion::kReplace_Op:
michael@0 269 return "replace";
michael@0 270 }
michael@0 271 return "unknown";
michael@0 272 }
michael@0 273
michael@0 274 void SkLua::pushClipStack(const SkClipStack& stack, const char* key) {
michael@0 275 lua_newtable(fL);
michael@0 276 SkClipStack::B2TIter iter(stack);
michael@0 277 const SkClipStack::Element* element;
michael@0 278 int i = 0;
michael@0 279 while (NULL != (element = iter.next())) {
michael@0 280 this->pushClipStackElement(*element);
michael@0 281 lua_rawseti(fL, -2, ++i);
michael@0 282 }
michael@0 283 CHECK_SETFIELD(key);
michael@0 284 }
michael@0 285
michael@0 286 void SkLua::pushClipStackElement(const SkClipStack::Element& element, const char* key) {
michael@0 287 lua_newtable(fL);
michael@0 288 SkClipStack::Element::Type type = element.getType();
michael@0 289 this->pushString(element_type(type), "type");
michael@0 290 switch (type) {
michael@0 291 case SkClipStack::Element::kEmpty_Type:
michael@0 292 break;
michael@0 293 case SkClipStack::Element::kRect_Type:
michael@0 294 this->pushRect(element.getRect(), "rect");
michael@0 295 break;
michael@0 296 case SkClipStack::Element::kRRect_Type:
michael@0 297 this->pushRRect(element.getRRect(), "rrect");
michael@0 298 break;
michael@0 299 case SkClipStack::Element::kPath_Type:
michael@0 300 this->pushPath(element.getPath(), "path");
michael@0 301 break;
michael@0 302 }
michael@0 303 this->pushString(region_op(element.getOp()), "op");
michael@0 304 this->pushBool(element.isAA(), "aa");
michael@0 305 CHECK_SETFIELD(key);
michael@0 306 }
michael@0 307
michael@0 308
michael@0 309 ///////////////////////////////////////////////////////////////////////////////
michael@0 310 ///////////////////////////////////////////////////////////////////////////////
michael@0 311
michael@0 312 static SkScalar lua2scalar(lua_State* L, int index) {
michael@0 313 SkASSERT(lua_isnumber(L, index));
michael@0 314 return SkLuaToScalar(lua_tonumber(L, index));
michael@0 315 }
michael@0 316
michael@0 317 static SkScalar lua2scalar_def(lua_State* L, int index, SkScalar defaultValue) {
michael@0 318 if (lua_isnumber(L, index)) {
michael@0 319 return SkLuaToScalar(lua_tonumber(L, index));
michael@0 320 } else {
michael@0 321 return defaultValue;
michael@0 322 }
michael@0 323 }
michael@0 324
michael@0 325 static SkScalar getfield_scalar(lua_State* L, int index, const char key[]) {
michael@0 326 SkASSERT(lua_istable(L, index));
michael@0 327 lua_pushstring(L, key);
michael@0 328 lua_gettable(L, index);
michael@0 329
michael@0 330 SkScalar value = lua2scalar(L, -1);
michael@0 331 lua_pop(L, 1);
michael@0 332 return value;
michael@0 333 }
michael@0 334
michael@0 335 static SkScalar getfield_scalar_default(lua_State* L, int index, const char key[], SkScalar def) {
michael@0 336 SkASSERT(lua_istable(L, index));
michael@0 337 lua_pushstring(L, key);
michael@0 338 lua_gettable(L, index);
michael@0 339
michael@0 340 SkScalar value;
michael@0 341 if (lua_isnil(L, -1)) {
michael@0 342 value = def;
michael@0 343 } else {
michael@0 344 value = lua2scalar(L, -1);
michael@0 345 }
michael@0 346 lua_pop(L, 1);
michael@0 347 return value;
michael@0 348 }
michael@0 349
michael@0 350 static U8CPU unit2byte(SkScalar x) {
michael@0 351 if (x <= 0) {
michael@0 352 return 0;
michael@0 353 } else if (x >= 1) {
michael@0 354 return 255;
michael@0 355 } else {
michael@0 356 return SkScalarRoundToInt(x * 255);
michael@0 357 }
michael@0 358 }
michael@0 359
michael@0 360 static SkColor lua2color(lua_State* L, int index) {
michael@0 361 return SkColorSetARGB(unit2byte(getfield_scalar(L, index, "a")),
michael@0 362 unit2byte(getfield_scalar(L, index, "r")),
michael@0 363 unit2byte(getfield_scalar(L, index, "g")),
michael@0 364 unit2byte(getfield_scalar(L, index, "b")));
michael@0 365 }
michael@0 366
michael@0 367 static SkRect* lua2rect(lua_State* L, int index, SkRect* rect) {
michael@0 368 rect->set(getfield_scalar_default(L, index, "left", 0),
michael@0 369 getfield_scalar_default(L, index, "top", 0),
michael@0 370 getfield_scalar(L, index, "right"),
michael@0 371 getfield_scalar(L, index, "bottom"));
michael@0 372 return rect;
michael@0 373 }
michael@0 374
michael@0 375 static int lcanvas_drawColor(lua_State* L) {
michael@0 376 get_ref<SkCanvas>(L, 1)->drawColor(lua2color(L, 2));
michael@0 377 return 0;
michael@0 378 }
michael@0 379
michael@0 380 static int lcanvas_drawRect(lua_State* L) {
michael@0 381 SkRect rect;
michael@0 382 get_ref<SkCanvas>(L, 1)->drawRect(*lua2rect(L, 2, &rect),
michael@0 383 *get_obj<SkPaint>(L, 3));
michael@0 384 return 0;
michael@0 385 }
michael@0 386
michael@0 387 static int lcanvas_drawOval(lua_State* L) {
michael@0 388 SkRect rect;
michael@0 389 get_ref<SkCanvas>(L, 1)->drawOval(*lua2rect(L, 2, &rect),
michael@0 390 *get_obj<SkPaint>(L, 3));
michael@0 391 return 0;
michael@0 392 }
michael@0 393
michael@0 394 static int lcanvas_drawCircle(lua_State* L) {
michael@0 395 get_ref<SkCanvas>(L, 1)->drawCircle(lua2scalar(L, 2),
michael@0 396 lua2scalar(L, 3),
michael@0 397 lua2scalar(L, 4),
michael@0 398 *get_obj<SkPaint>(L, 5));
michael@0 399 return 0;
michael@0 400 }
michael@0 401
michael@0 402 static int lcanvas_drawImage(lua_State* L) {
michael@0 403 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
michael@0 404 SkImage* image = get_ref<SkImage>(L, 2);
michael@0 405 if (NULL == image) {
michael@0 406 return 0;
michael@0 407 }
michael@0 408 SkScalar x = lua2scalar(L, 3);
michael@0 409 SkScalar y = lua2scalar(L, 4);
michael@0 410
michael@0 411 SkPaint paint;
michael@0 412 const SkPaint* paintPtr = NULL;
michael@0 413 if (lua_isnumber(L, 5)) {
michael@0 414 paint.setAlpha(SkScalarRoundToInt(lua2scalar(L, 5) * 255));
michael@0 415 paintPtr = &paint;
michael@0 416 }
michael@0 417 image->draw(canvas, x, y, paintPtr);
michael@0 418 return 0;
michael@0 419 }
michael@0 420
michael@0 421 static int lcanvas_drawPath(lua_State* L) {
michael@0 422 get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
michael@0 423 *get_obj<SkPaint>(L, 3));
michael@0 424 return 0;
michael@0 425 }
michael@0 426
michael@0 427 static int lcanvas_drawText(lua_State* L) {
michael@0 428 if (lua_gettop(L) < 5) {
michael@0 429 return 0;
michael@0 430 }
michael@0 431
michael@0 432 if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
michael@0 433 size_t len;
michael@0 434 const char* text = lua_tolstring(L, 2, &len);
michael@0 435 get_ref<SkCanvas>(L, 1)->drawText(text, len,
michael@0 436 lua2scalar(L, 3), lua2scalar(L, 4),
michael@0 437 *get_obj<SkPaint>(L, 5));
michael@0 438 }
michael@0 439 return 0;
michael@0 440 }
michael@0 441
michael@0 442 static int lcanvas_getSaveCount(lua_State* L) {
michael@0 443 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
michael@0 444 return 1;
michael@0 445 }
michael@0 446
michael@0 447 static int lcanvas_getTotalMatrix(lua_State* L) {
michael@0 448 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
michael@0 449 return 1;
michael@0 450 }
michael@0 451
michael@0 452 static int lcanvas_getClipStack(lua_State* L) {
michael@0 453 SkLua(L).pushClipStack(*get_ref<SkCanvas>(L, 1)->getClipStack());
michael@0 454 return 1;
michael@0 455 }
michael@0 456
michael@0 457 int SkLua::lcanvas_getReducedClipStack(lua_State* L) {
michael@0 458 #if SK_SUPPORT_GPU
michael@0 459 const SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
michael@0 460 SkISize layerSize = canvas->getTopLayerSize();
michael@0 461 SkIPoint layerOrigin = canvas->getTopLayerOrigin();
michael@0 462 SkIRect queryBounds = SkIRect::MakeXYWH(layerOrigin.fX, layerOrigin.fY,
michael@0 463 layerSize.fWidth, layerSize.fHeight);
michael@0 464
michael@0 465 GrReducedClip::ElementList elements;
michael@0 466 GrReducedClip::InitialState initialState;
michael@0 467 int32_t genID;
michael@0 468 SkIRect resultBounds;
michael@0 469
michael@0 470 const SkClipStack& stack = *canvas->getClipStack();
michael@0 471
michael@0 472 GrReducedClip::ReduceClipStack(stack,
michael@0 473 queryBounds,
michael@0 474 &elements,
michael@0 475 &genID,
michael@0 476 &initialState,
michael@0 477 &resultBounds,
michael@0 478 NULL);
michael@0 479
michael@0 480 GrReducedClip::ElementList::Iter iter(elements);
michael@0 481 int i = 0;
michael@0 482 lua_newtable(L);
michael@0 483 while(NULL != iter.get()) {
michael@0 484 SkLua(L).pushClipStackElement(*iter.get());
michael@0 485 iter.next();
michael@0 486 lua_rawseti(L, -2, ++i);
michael@0 487 }
michael@0 488 // Currently this only returns the element list to lua, not the initial state or result bounds.
michael@0 489 // It could return these as additional items on the lua stack.
michael@0 490 return 1;
michael@0 491 #else
michael@0 492 return 0;
michael@0 493 #endif
michael@0 494 }
michael@0 495
michael@0 496 static int lcanvas_save(lua_State* L) {
michael@0 497 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->save());
michael@0 498 return 1;
michael@0 499 }
michael@0 500
michael@0 501 static int lcanvas_restore(lua_State* L) {
michael@0 502 get_ref<SkCanvas>(L, 1)->restore();
michael@0 503 return 0;
michael@0 504 }
michael@0 505
michael@0 506 static int lcanvas_scale(lua_State* L) {
michael@0 507 SkScalar sx = lua2scalar_def(L, 2, 1);
michael@0 508 SkScalar sy = lua2scalar_def(L, 3, sx);
michael@0 509 get_ref<SkCanvas>(L, 1)->scale(sx, sy);
michael@0 510 return 0;
michael@0 511 }
michael@0 512
michael@0 513 static int lcanvas_translate(lua_State* L) {
michael@0 514 SkScalar tx = lua2scalar_def(L, 2, 0);
michael@0 515 SkScalar ty = lua2scalar_def(L, 3, 0);
michael@0 516 get_ref<SkCanvas>(L, 1)->translate(tx, ty);
michael@0 517 return 0;
michael@0 518 }
michael@0 519
michael@0 520 static int lcanvas_rotate(lua_State* L) {
michael@0 521 SkScalar degrees = lua2scalar_def(L, 2, 0);
michael@0 522 get_ref<SkCanvas>(L, 1)->rotate(degrees);
michael@0 523 return 0;
michael@0 524 }
michael@0 525
michael@0 526 static int lcanvas_gc(lua_State* L) {
michael@0 527 get_ref<SkCanvas>(L, 1)->unref();
michael@0 528 return 0;
michael@0 529 }
michael@0 530
michael@0 531 const struct luaL_Reg gSkCanvas_Methods[] = {
michael@0 532 { "drawColor", lcanvas_drawColor },
michael@0 533 { "drawRect", lcanvas_drawRect },
michael@0 534 { "drawOval", lcanvas_drawOval },
michael@0 535 { "drawCircle", lcanvas_drawCircle },
michael@0 536 { "drawImage", lcanvas_drawImage },
michael@0 537 { "drawPath", lcanvas_drawPath },
michael@0 538 { "drawText", lcanvas_drawText },
michael@0 539 { "getSaveCount", lcanvas_getSaveCount },
michael@0 540 { "getTotalMatrix", lcanvas_getTotalMatrix },
michael@0 541 { "getClipStack", lcanvas_getClipStack },
michael@0 542 #if SK_SUPPORT_GPU
michael@0 543 { "getReducedClipStack", SkLua::lcanvas_getReducedClipStack },
michael@0 544 #endif
michael@0 545 { "save", lcanvas_save },
michael@0 546 { "restore", lcanvas_restore },
michael@0 547 { "scale", lcanvas_scale },
michael@0 548 { "translate", lcanvas_translate },
michael@0 549 { "rotate", lcanvas_rotate },
michael@0 550 { "__gc", lcanvas_gc },
michael@0 551 { NULL, NULL }
michael@0 552 };
michael@0 553
michael@0 554 ///////////////////////////////////////////////////////////////////////////////
michael@0 555
michael@0 556 static int ldocument_beginPage(lua_State* L) {
michael@0 557 const SkRect* contentPtr = NULL;
michael@0 558 push_ref(L, get_ref<SkDocument>(L, 1)->beginPage(lua2scalar(L, 2),
michael@0 559 lua2scalar(L, 3),
michael@0 560 contentPtr));
michael@0 561 return 1;
michael@0 562 }
michael@0 563
michael@0 564 static int ldocument_endPage(lua_State* L) {
michael@0 565 get_ref<SkDocument>(L, 1)->endPage();
michael@0 566 return 0;
michael@0 567 }
michael@0 568
michael@0 569 static int ldocument_close(lua_State* L) {
michael@0 570 get_ref<SkDocument>(L, 1)->close();
michael@0 571 return 0;
michael@0 572 }
michael@0 573
michael@0 574 static int ldocument_gc(lua_State* L) {
michael@0 575 get_ref<SkDocument>(L, 1)->unref();
michael@0 576 return 0;
michael@0 577 }
michael@0 578
michael@0 579 static const struct luaL_Reg gSkDocument_Methods[] = {
michael@0 580 { "beginPage", ldocument_beginPage },
michael@0 581 { "endPage", ldocument_endPage },
michael@0 582 { "close", ldocument_close },
michael@0 583 { "__gc", ldocument_gc },
michael@0 584 { NULL, NULL }
michael@0 585 };
michael@0 586
michael@0 587 ///////////////////////////////////////////////////////////////////////////////
michael@0 588
michael@0 589 static int lpaint_isAntiAlias(lua_State* L) {
michael@0 590 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
michael@0 591 return 1;
michael@0 592 }
michael@0 593
michael@0 594 static int lpaint_setAntiAlias(lua_State* L) {
michael@0 595 get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
michael@0 596 return 0;
michael@0 597 }
michael@0 598
michael@0 599 static int lpaint_isDither(lua_State* L) {
michael@0 600 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
michael@0 601 return 1;
michael@0 602 }
michael@0 603
michael@0 604 static int lpaint_isUnderlineText(lua_State* L) {
michael@0 605 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isUnderlineText());
michael@0 606 return 1;
michael@0 607 }
michael@0 608
michael@0 609 static int lpaint_isStrikeThruText(lua_State* L) {
michael@0 610 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isStrikeThruText());
michael@0 611 return 1;
michael@0 612 }
michael@0 613
michael@0 614 static int lpaint_isFakeBoldText(lua_State* L) {
michael@0 615 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isFakeBoldText());
michael@0 616 return 1;
michael@0 617 }
michael@0 618
michael@0 619 static int lpaint_isLinearText(lua_State* L) {
michael@0 620 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLinearText());
michael@0 621 return 1;
michael@0 622 }
michael@0 623
michael@0 624 static int lpaint_isSubpixelText(lua_State* L) {
michael@0 625 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isSubpixelText());
michael@0 626 return 1;
michael@0 627 }
michael@0 628
michael@0 629 static int lpaint_isDevKernText(lua_State* L) {
michael@0 630 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDevKernText());
michael@0 631 return 1;
michael@0 632 }
michael@0 633
michael@0 634 static int lpaint_isLCDRenderText(lua_State* L) {
michael@0 635 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLCDRenderText());
michael@0 636 return 1;
michael@0 637 }
michael@0 638
michael@0 639 static int lpaint_isEmbeddedBitmapText(lua_State* L) {
michael@0 640 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isEmbeddedBitmapText());
michael@0 641 return 1;
michael@0 642 }
michael@0 643
michael@0 644 static int lpaint_isAutohinted(lua_State* L) {
michael@0 645 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAutohinted());
michael@0 646 return 1;
michael@0 647 }
michael@0 648
michael@0 649 static int lpaint_isVerticalText(lua_State* L) {
michael@0 650 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isVerticalText());
michael@0 651 return 1;
michael@0 652 }
michael@0 653
michael@0 654 static int lpaint_getColor(lua_State* L) {
michael@0 655 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
michael@0 656 return 1;
michael@0 657 }
michael@0 658
michael@0 659 static int lpaint_setColor(lua_State* L) {
michael@0 660 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
michael@0 661 return 0;
michael@0 662 }
michael@0 663
michael@0 664 static int lpaint_getTextSize(lua_State* L) {
michael@0 665 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSize());
michael@0 666 return 1;
michael@0 667 }
michael@0 668
michael@0 669 static int lpaint_getTextScaleX(lua_State* L) {
michael@0 670 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextScaleX());
michael@0 671 return 1;
michael@0 672 }
michael@0 673
michael@0 674 static int lpaint_getTextSkewX(lua_State* L) {
michael@0 675 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSkewX());
michael@0 676 return 1;
michael@0 677 }
michael@0 678
michael@0 679 static int lpaint_setTextSize(lua_State* L) {
michael@0 680 get_obj<SkPaint>(L, 1)->setTextSize(lua2scalar(L, 2));
michael@0 681 return 0;
michael@0 682 }
michael@0 683
michael@0 684 static int lpaint_getTypeface(lua_State* L) {
michael@0 685 push_ref(L, get_obj<SkPaint>(L, 1)->getTypeface());
michael@0 686 return 1;
michael@0 687 }
michael@0 688
michael@0 689 static int lpaint_setTypeface(lua_State* L) {
michael@0 690 get_obj<SkPaint>(L, 1)->setTypeface(get_ref<SkTypeface>(L, 2));
michael@0 691 return 0;
michael@0 692 }
michael@0 693
michael@0 694 static int lpaint_getHinting(lua_State* L) {
michael@0 695 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getHinting());
michael@0 696 return 1;
michael@0 697 }
michael@0 698
michael@0 699 static int lpaint_getFontID(lua_State* L) {
michael@0 700 SkTypeface* face = get_obj<SkPaint>(L, 1)->getTypeface();
michael@0 701 SkLua(L).pushU32(SkTypeface::UniqueID(face));
michael@0 702 return 1;
michael@0 703 }
michael@0 704
michael@0 705 static const struct {
michael@0 706 const char* fLabel;
michael@0 707 SkPaint::Align fAlign;
michael@0 708 } gAlignRec[] = {
michael@0 709 { "left", SkPaint::kLeft_Align },
michael@0 710 { "center", SkPaint::kCenter_Align },
michael@0 711 { "right", SkPaint::kRight_Align },
michael@0 712 };
michael@0 713
michael@0 714 static int lpaint_getTextAlign(lua_State* L) {
michael@0 715 SkPaint::Align align = get_obj<SkPaint>(L, 1)->getTextAlign();
michael@0 716 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
michael@0 717 if (gAlignRec[i].fAlign == align) {
michael@0 718 lua_pushstring(L, gAlignRec[i].fLabel);
michael@0 719 return 1;
michael@0 720 }
michael@0 721 }
michael@0 722 return 0;
michael@0 723 }
michael@0 724
michael@0 725 static int lpaint_setTextAlign(lua_State* L) {
michael@0 726 if (lua_isstring(L, 2)) {
michael@0 727 size_t len;
michael@0 728 const char* label = lua_tolstring(L, 2, &len);
michael@0 729
michael@0 730 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
michael@0 731 if (!strcmp(gAlignRec[i].fLabel, label)) {
michael@0 732 get_obj<SkPaint>(L, 1)->setTextAlign(gAlignRec[i].fAlign);
michael@0 733 break;
michael@0 734 }
michael@0 735 }
michael@0 736 }
michael@0 737 return 0;
michael@0 738 }
michael@0 739
michael@0 740 static int lpaint_getStroke(lua_State* L) {
michael@0 741 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
michael@0 742 return 1;
michael@0 743 }
michael@0 744
michael@0 745 static int lpaint_setStroke(lua_State* L) {
michael@0 746 SkPaint::Style style;
michael@0 747
michael@0 748 if (lua_toboolean(L, 2)) {
michael@0 749 style = SkPaint::kStroke_Style;
michael@0 750 } else {
michael@0 751 style = SkPaint::kFill_Style;
michael@0 752 }
michael@0 753 get_obj<SkPaint>(L, 1)->setStyle(style);
michael@0 754 return 0;
michael@0 755 }
michael@0 756
michael@0 757 static int lpaint_getStrokeCap(lua_State* L) {
michael@0 758 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
michael@0 759 return 1;
michael@0 760 }
michael@0 761
michael@0 762 static int lpaint_getStrokeJoin(lua_State* L) {
michael@0 763 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
michael@0 764 return 1;
michael@0 765 }
michael@0 766
michael@0 767 static int lpaint_getTextEncoding(lua_State* L) {
michael@0 768 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getTextEncoding());
michael@0 769 return 1;
michael@0 770 }
michael@0 771
michael@0 772 static int lpaint_getStrokeWidth(lua_State* L) {
michael@0 773 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
michael@0 774 return 1;
michael@0 775 }
michael@0 776
michael@0 777 static int lpaint_setStrokeWidth(lua_State* L) {
michael@0 778 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
michael@0 779 return 0;
michael@0 780 }
michael@0 781
michael@0 782 static int lpaint_getStrokeMiter(lua_State* L) {
michael@0 783 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
michael@0 784 return 1;
michael@0 785 }
michael@0 786
michael@0 787 static int lpaint_measureText(lua_State* L) {
michael@0 788 if (lua_isstring(L, 2)) {
michael@0 789 size_t len;
michael@0 790 const char* text = lua_tolstring(L, 2, &len);
michael@0 791 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->measureText(text, len));
michael@0 792 return 1;
michael@0 793 }
michael@0 794 return 0;
michael@0 795 }
michael@0 796
michael@0 797 struct FontMetrics {
michael@0 798 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
michael@0 799 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
michael@0 800 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
michael@0 801 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
michael@0 802 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
michael@0 803 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
michael@0 804 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
michael@0 805 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
michael@0 806 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
michael@0 807 };
michael@0 808
michael@0 809 static int lpaint_getFontMetrics(lua_State* L) {
michael@0 810 SkPaint::FontMetrics fm;
michael@0 811 SkScalar height = get_obj<SkPaint>(L, 1)->getFontMetrics(&fm);
michael@0 812
michael@0 813 lua_newtable(L);
michael@0 814 setfield_scalar(L, "top", fm.fTop);
michael@0 815 setfield_scalar(L, "ascent", fm.fAscent);
michael@0 816 setfield_scalar(L, "descent", fm.fDescent);
michael@0 817 setfield_scalar(L, "bottom", fm.fBottom);
michael@0 818 setfield_scalar(L, "leading", fm.fLeading);
michael@0 819 SkLua(L).pushScalar(height);
michael@0 820 return 2;
michael@0 821 }
michael@0 822
michael@0 823 static int lpaint_getEffects(lua_State* L) {
michael@0 824 const SkPaint* paint = get_obj<SkPaint>(L, 1);
michael@0 825
michael@0 826 lua_newtable(L);
michael@0 827 setfield_bool_if(L, "looper", !!paint->getLooper());
michael@0 828 setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
michael@0 829 setfield_bool_if(L, "rasterizer", !!paint->getRasterizer());
michael@0 830 setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
michael@0 831 setfield_bool_if(L, "shader", !!paint->getShader());
michael@0 832 setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
michael@0 833 setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
michael@0 834 setfield_bool_if(L, "xfermode", !!paint->getXfermode());
michael@0 835 return 1;
michael@0 836 }
michael@0 837
michael@0 838 static int lpaint_getShader(lua_State* L) {
michael@0 839 const SkPaint* paint = get_obj<SkPaint>(L, 1);
michael@0 840 SkShader* shader = paint->getShader();
michael@0 841 if (shader) {
michael@0 842 push_ref(L, shader);
michael@0 843 return 1;
michael@0 844 }
michael@0 845 return 0;
michael@0 846 }
michael@0 847
michael@0 848 static int lpaint_gc(lua_State* L) {
michael@0 849 get_obj<SkPaint>(L, 1)->~SkPaint();
michael@0 850 return 0;
michael@0 851 }
michael@0 852
michael@0 853 static const struct luaL_Reg gSkPaint_Methods[] = {
michael@0 854 { "isAntiAlias", lpaint_isAntiAlias },
michael@0 855 { "setAntiAlias", lpaint_setAntiAlias },
michael@0 856 { "isDither", lpaint_isDither },
michael@0 857 { "isUnderlineText", lpaint_isUnderlineText },
michael@0 858 { "isStrikeThruText", lpaint_isStrikeThruText },
michael@0 859 { "isFakeBoldText", lpaint_isFakeBoldText },
michael@0 860 { "isLinearText", lpaint_isLinearText },
michael@0 861 { "isSubpixelText", lpaint_isSubpixelText },
michael@0 862 { "isDevKernText", lpaint_isDevKernText },
michael@0 863 { "isLCDRenderText", lpaint_isLCDRenderText },
michael@0 864 { "isEmbeddedBitmapText", lpaint_isEmbeddedBitmapText },
michael@0 865 { "isAutohinted", lpaint_isAutohinted },
michael@0 866 { "isVerticalText", lpaint_isVerticalText },
michael@0 867 { "getColor", lpaint_getColor },
michael@0 868 { "setColor", lpaint_setColor },
michael@0 869 { "getTextSize", lpaint_getTextSize },
michael@0 870 { "setTextSize", lpaint_setTextSize },
michael@0 871 { "getTextScaleX", lpaint_getTextScaleX },
michael@0 872 { "getTextSkewX", lpaint_getTextSkewX },
michael@0 873 { "getTypeface", lpaint_getTypeface },
michael@0 874 { "setTypeface", lpaint_setTypeface },
michael@0 875 { "getHinting", lpaint_getHinting },
michael@0 876 { "getFontID", lpaint_getFontID },
michael@0 877 { "getTextAlign", lpaint_getTextAlign },
michael@0 878 { "setTextAlign", lpaint_setTextAlign },
michael@0 879 { "getStroke", lpaint_getStroke },
michael@0 880 { "setStroke", lpaint_setStroke },
michael@0 881 { "getStrokeCap", lpaint_getStrokeCap },
michael@0 882 { "getStrokeJoin", lpaint_getStrokeJoin },
michael@0 883 { "getTextEncoding", lpaint_getTextEncoding },
michael@0 884 { "getStrokeWidth", lpaint_getStrokeWidth },
michael@0 885 { "setStrokeWidth", lpaint_setStrokeWidth },
michael@0 886 { "getStrokeMiter", lpaint_getStrokeMiter },
michael@0 887 { "measureText", lpaint_measureText },
michael@0 888 { "getFontMetrics", lpaint_getFontMetrics },
michael@0 889 { "getEffects", lpaint_getEffects },
michael@0 890 { "getShader", lpaint_getShader },
michael@0 891 { "__gc", lpaint_gc },
michael@0 892 { NULL, NULL }
michael@0 893 };
michael@0 894
michael@0 895 ///////////////////////////////////////////////////////////////////////////////
michael@0 896
michael@0 897 static const char* mode2string(SkShader::TileMode mode) {
michael@0 898 static const char* gNames[] = { "clamp", "repeat", "mirror" };
michael@0 899 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
michael@0 900 return gNames[mode];
michael@0 901 }
michael@0 902
michael@0 903 static const char* gradtype2string(SkShader::GradientType t) {
michael@0 904 static const char* gNames[] = {
michael@0 905 "none", "color", "linear", "radial", "radial2", "sweep", "conical"
michael@0 906 };
michael@0 907 SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
michael@0 908 return gNames[t];
michael@0 909 }
michael@0 910
michael@0 911 static int lshader_isOpaque(lua_State* L) {
michael@0 912 SkShader* shader = get_ref<SkShader>(L, 1);
michael@0 913 return shader && shader->isOpaque();
michael@0 914 }
michael@0 915
michael@0 916 static int lshader_asABitmap(lua_State* L) {
michael@0 917 SkShader* shader = get_ref<SkShader>(L, 1);
michael@0 918 if (shader) {
michael@0 919 SkBitmap bm;
michael@0 920 SkMatrix matrix;
michael@0 921 SkShader::TileMode modes[2];
michael@0 922 switch (shader->asABitmap(&bm, &matrix, modes)) {
michael@0 923 case SkShader::kDefault_BitmapType:
michael@0 924 lua_newtable(L);
michael@0 925 setfield_number(L, "genID", bm.pixelRef() ? bm.pixelRef()->getGenerationID() : 0);
michael@0 926 setfield_number(L, "width", bm.width());
michael@0 927 setfield_number(L, "height", bm.height());
michael@0 928 setfield_string(L, "tileX", mode2string(modes[0]));
michael@0 929 setfield_string(L, "tileY", mode2string(modes[1]));
michael@0 930 return 1;
michael@0 931 default:
michael@0 932 break;
michael@0 933 }
michael@0 934 }
michael@0 935 return 0;
michael@0 936 }
michael@0 937
michael@0 938 static int lshader_asAGradient(lua_State* L) {
michael@0 939 SkShader* shader = get_ref<SkShader>(L, 1);
michael@0 940 if (shader) {
michael@0 941 SkShader::GradientInfo info;
michael@0 942 sk_bzero(&info, sizeof(info));
michael@0 943
michael@0 944 SkColor colors[3]; // hacked in for extracting info on 3 color case.
michael@0 945 SkScalar pos[3];
michael@0 946
michael@0 947 info.fColorCount = 3;
michael@0 948 info.fColors = &colors[0];
michael@0 949 info.fColorOffsets = &pos[0];
michael@0 950
michael@0 951 SkShader::GradientType t = shader->asAGradient(&info);
michael@0 952
michael@0 953 if (SkShader::kNone_GradientType != t) {
michael@0 954 lua_newtable(L);
michael@0 955 setfield_string(L, "type", gradtype2string(t));
michael@0 956 setfield_number(L, "colorCount", info.fColorCount);
michael@0 957 setfield_string(L, "tile", mode2string(info.fTileMode));
michael@0 958
michael@0 959 if (info.fColorCount == 3){
michael@0 960 setfield_number(L, "midPos", pos[1]);
michael@0 961 }
michael@0 962
michael@0 963 return 1;
michael@0 964 }
michael@0 965 }
michael@0 966 return 0;
michael@0 967 }
michael@0 968
michael@0 969 static int lshader_gc(lua_State* L) {
michael@0 970 get_ref<SkShader>(L, 1)->unref();
michael@0 971 return 0;
michael@0 972 }
michael@0 973
michael@0 974 static const struct luaL_Reg gSkShader_Methods[] = {
michael@0 975 { "isOpaque", lshader_isOpaque },
michael@0 976 { "asABitmap", lshader_asABitmap },
michael@0 977 { "asAGradient", lshader_asAGradient },
michael@0 978 { "__gc", lshader_gc },
michael@0 979 { NULL, NULL }
michael@0 980 };
michael@0 981
michael@0 982 ///////////////////////////////////////////////////////////////////////////////
michael@0 983
michael@0 984 static int lmatrix_getType(lua_State* L) {
michael@0 985 SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
michael@0 986
michael@0 987 lua_newtable(L);
michael@0 988 setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
michael@0 989 setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
michael@0 990 setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
michael@0 991 setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
michael@0 992 return 1;
michael@0 993 }
michael@0 994
michael@0 995 static int lmatrix_getScaleX(lua_State* L) {
michael@0 996 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
michael@0 997 return 1;
michael@0 998 }
michael@0 999
michael@0 1000 static int lmatrix_getScaleY(lua_State* L) {
michael@0 1001 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
michael@0 1002 return 1;
michael@0 1003 }
michael@0 1004
michael@0 1005 static int lmatrix_getTranslateX(lua_State* L) {
michael@0 1006 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
michael@0 1007 return 1;
michael@0 1008 }
michael@0 1009
michael@0 1010 static int lmatrix_getTranslateY(lua_State* L) {
michael@0 1011 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
michael@0 1012 return 1;
michael@0 1013 }
michael@0 1014
michael@0 1015 static const struct luaL_Reg gSkMatrix_Methods[] = {
michael@0 1016 { "getType", lmatrix_getType },
michael@0 1017 { "getScaleX", lmatrix_getScaleX },
michael@0 1018 { "getScaleY", lmatrix_getScaleY },
michael@0 1019 { "getTranslateX", lmatrix_getTranslateX },
michael@0 1020 { "getTranslateY", lmatrix_getTranslateY },
michael@0 1021 { NULL, NULL }
michael@0 1022 };
michael@0 1023
michael@0 1024 ///////////////////////////////////////////////////////////////////////////////
michael@0 1025
michael@0 1026 static int lpath_getBounds(lua_State* L) {
michael@0 1027 SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
michael@0 1028 return 1;
michael@0 1029 }
michael@0 1030
michael@0 1031 static const char* fill_type_to_str(SkPath::FillType fill) {
michael@0 1032 switch (fill) {
michael@0 1033 case SkPath::kEvenOdd_FillType:
michael@0 1034 return "even-odd";
michael@0 1035 case SkPath::kWinding_FillType:
michael@0 1036 return "winding";
michael@0 1037 case SkPath::kInverseEvenOdd_FillType:
michael@0 1038 return "inverse-even-odd";
michael@0 1039 case SkPath::kInverseWinding_FillType:
michael@0 1040 return "inverse-winding";
michael@0 1041 }
michael@0 1042 return "unknown";
michael@0 1043 }
michael@0 1044
michael@0 1045 static int lpath_getFillType(lua_State* L) {
michael@0 1046 SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
michael@0 1047 SkLua(L).pushString(fill_type_to_str(fill));
michael@0 1048 return 1;
michael@0 1049 }
michael@0 1050
michael@0 1051 static SkString segment_masks_to_str(uint32_t segmentMasks) {
michael@0 1052 SkString result;
michael@0 1053 bool first = true;
michael@0 1054 if (SkPath::kLine_SegmentMask & segmentMasks) {
michael@0 1055 result.append("line");
michael@0 1056 first = false;
michael@0 1057 SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
michael@0 1058 }
michael@0 1059 if (SkPath::kQuad_SegmentMask & segmentMasks) {
michael@0 1060 if (!first) {
michael@0 1061 result.append(" ");
michael@0 1062 }
michael@0 1063 result.append("quad");
michael@0 1064 first = false;
michael@0 1065 SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
michael@0 1066 }
michael@0 1067 if (SkPath::kConic_SegmentMask & segmentMasks) {
michael@0 1068 if (!first) {
michael@0 1069 result.append(" ");
michael@0 1070 }
michael@0 1071 result.append("conic");
michael@0 1072 first = false;
michael@0 1073 SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
michael@0 1074 }
michael@0 1075 if (SkPath::kCubic_SegmentMask & segmentMasks) {
michael@0 1076 if (!first) {
michael@0 1077 result.append(" ");
michael@0 1078 }
michael@0 1079 result.append("cubic");
michael@0 1080 SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
michael@0 1081 }
michael@0 1082 SkASSERT(0 == segmentMasks);
michael@0 1083 return result;
michael@0 1084 }
michael@0 1085
michael@0 1086 static int lpath_getSegementTypes(lua_State* L) {
michael@0 1087 uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
michael@0 1088 SkLua(L).pushString(segment_masks_to_str(segMasks));
michael@0 1089 return 1;
michael@0 1090 }
michael@0 1091
michael@0 1092 static int lpath_isConvex(lua_State* L) {
michael@0 1093 bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
michael@0 1094 SkLua(L).pushBool(isConvex);
michael@0 1095 return 1;
michael@0 1096 }
michael@0 1097
michael@0 1098 static int lpath_isEmpty(lua_State* L) {
michael@0 1099 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
michael@0 1100 return 1;
michael@0 1101 }
michael@0 1102
michael@0 1103 static int lpath_isRect(lua_State* L) {
michael@0 1104 SkRect r;
michael@0 1105 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
michael@0 1106 int ret_count = 1;
michael@0 1107 lua_pushboolean(L, pred);
michael@0 1108 if (pred) {
michael@0 1109 SkLua(L).pushRect(r);
michael@0 1110 ret_count += 1;
michael@0 1111 }
michael@0 1112 return ret_count;
michael@0 1113 }
michael@0 1114
michael@0 1115 static const char* dir2string(SkPath::Direction dir) {
michael@0 1116 static const char* gStr[] = {
michael@0 1117 "unknown", "cw", "ccw"
michael@0 1118 };
michael@0 1119 SkASSERT((unsigned)dir < SK_ARRAY_COUNT(gStr));
michael@0 1120 return gStr[dir];
michael@0 1121 }
michael@0 1122
michael@0 1123 static int lpath_isNestedRects(lua_State* L) {
michael@0 1124 SkRect rects[2];
michael@0 1125 SkPath::Direction dirs[2];
michael@0 1126 bool pred = get_obj<SkPath>(L, 1)->isNestedRects(rects, dirs);
michael@0 1127 int ret_count = 1;
michael@0 1128 lua_pushboolean(L, pred);
michael@0 1129 if (pred) {
michael@0 1130 SkLua lua(L);
michael@0 1131 lua.pushRect(rects[0]);
michael@0 1132 lua.pushRect(rects[1]);
michael@0 1133 lua_pushstring(L, dir2string(dirs[0]));
michael@0 1134 lua_pushstring(L, dir2string(dirs[0]));
michael@0 1135 ret_count += 4;
michael@0 1136 }
michael@0 1137 return ret_count;
michael@0 1138 }
michael@0 1139
michael@0 1140 static int lpath_countPoints(lua_State* L) {
michael@0 1141 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
michael@0 1142 return 1;
michael@0 1143 }
michael@0 1144
michael@0 1145 static int lpath_reset(lua_State* L) {
michael@0 1146 get_obj<SkPath>(L, 1)->reset();
michael@0 1147 return 0;
michael@0 1148 }
michael@0 1149
michael@0 1150 static int lpath_moveTo(lua_State* L) {
michael@0 1151 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
michael@0 1152 return 0;
michael@0 1153 }
michael@0 1154
michael@0 1155 static int lpath_lineTo(lua_State* L) {
michael@0 1156 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
michael@0 1157 return 0;
michael@0 1158 }
michael@0 1159
michael@0 1160 static int lpath_quadTo(lua_State* L) {
michael@0 1161 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
michael@0 1162 lua2scalar(L, 4), lua2scalar(L, 5));
michael@0 1163 return 0;
michael@0 1164 }
michael@0 1165
michael@0 1166 static int lpath_cubicTo(lua_State* L) {
michael@0 1167 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
michael@0 1168 lua2scalar(L, 4), lua2scalar(L, 5),
michael@0 1169 lua2scalar(L, 6), lua2scalar(L, 7));
michael@0 1170 return 0;
michael@0 1171 }
michael@0 1172
michael@0 1173 static int lpath_close(lua_State* L) {
michael@0 1174 get_obj<SkPath>(L, 1)->close();
michael@0 1175 return 0;
michael@0 1176 }
michael@0 1177
michael@0 1178 static int lpath_gc(lua_State* L) {
michael@0 1179 get_obj<SkPath>(L, 1)->~SkPath();
michael@0 1180 return 0;
michael@0 1181 }
michael@0 1182
michael@0 1183 static const struct luaL_Reg gSkPath_Methods[] = {
michael@0 1184 { "getBounds", lpath_getBounds },
michael@0 1185 { "getFillType", lpath_getFillType },
michael@0 1186 { "getSegmentTypes", lpath_getSegementTypes },
michael@0 1187 { "isConvex", lpath_isConvex },
michael@0 1188 { "isEmpty", lpath_isEmpty },
michael@0 1189 { "isRect", lpath_isRect },
michael@0 1190 { "isNestedRects", lpath_isNestedRects },
michael@0 1191 { "countPoints", lpath_countPoints },
michael@0 1192 { "reset", lpath_reset },
michael@0 1193 { "moveTo", lpath_moveTo },
michael@0 1194 { "lineTo", lpath_lineTo },
michael@0 1195 { "quadTo", lpath_quadTo },
michael@0 1196 { "cubicTo", lpath_cubicTo },
michael@0 1197 { "close", lpath_close },
michael@0 1198 { "__gc", lpath_gc },
michael@0 1199 { NULL, NULL }
michael@0 1200 };
michael@0 1201
michael@0 1202 ///////////////////////////////////////////////////////////////////////////////
michael@0 1203
michael@0 1204 static const char* rrect_type(const SkRRect& rr) {
michael@0 1205 switch (rr.getType()) {
michael@0 1206 case SkRRect::kUnknown_Type: return "unknown";
michael@0 1207 case SkRRect::kEmpty_Type: return "empty";
michael@0 1208 case SkRRect::kRect_Type: return "rect";
michael@0 1209 case SkRRect::kOval_Type: return "oval";
michael@0 1210 case SkRRect::kSimple_Type: return "simple";
michael@0 1211 case SkRRect::kComplex_Type: return "complex";
michael@0 1212 }
michael@0 1213 SkDEBUGFAIL("never get here");
michael@0 1214 return "";
michael@0 1215 }
michael@0 1216
michael@0 1217 static int lrrect_rect(lua_State* L) {
michael@0 1218 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
michael@0 1219 return 1;
michael@0 1220 }
michael@0 1221
michael@0 1222 static int lrrect_type(lua_State* L) {
michael@0 1223 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
michael@0 1224 return 1;
michael@0 1225 }
michael@0 1226
michael@0 1227 static int lrrect_radii(lua_State* L) {
michael@0 1228 int corner = SkToInt(lua_tointeger(L, 2));
michael@0 1229 SkVector v;
michael@0 1230 if (corner < 0 || corner > 3) {
michael@0 1231 SkDebugf("bad corner index %d", corner);
michael@0 1232 v.set(0, 0);
michael@0 1233 } else {
michael@0 1234 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
michael@0 1235 }
michael@0 1236 lua_pushnumber(L, v.fX);
michael@0 1237 lua_pushnumber(L, v.fY);
michael@0 1238 return 2;
michael@0 1239 }
michael@0 1240
michael@0 1241 static int lrrect_gc(lua_State* L) {
michael@0 1242 get_obj<SkRRect>(L, 1)->~SkRRect();
michael@0 1243 return 0;
michael@0 1244 }
michael@0 1245
michael@0 1246 static const struct luaL_Reg gSkRRect_Methods[] = {
michael@0 1247 { "rect", lrrect_rect },
michael@0 1248 { "type", lrrect_type },
michael@0 1249 { "radii", lrrect_radii },
michael@0 1250 { "__gc", lrrect_gc },
michael@0 1251 { NULL, NULL }
michael@0 1252 };
michael@0 1253
michael@0 1254 ///////////////////////////////////////////////////////////////////////////////
michael@0 1255
michael@0 1256 static int limage_width(lua_State* L) {
michael@0 1257 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
michael@0 1258 return 1;
michael@0 1259 }
michael@0 1260
michael@0 1261 static int limage_height(lua_State* L) {
michael@0 1262 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
michael@0 1263 return 1;
michael@0 1264 }
michael@0 1265
michael@0 1266 static int limage_gc(lua_State* L) {
michael@0 1267 get_ref<SkImage>(L, 1)->unref();
michael@0 1268 return 0;
michael@0 1269 }
michael@0 1270
michael@0 1271 static const struct luaL_Reg gSkImage_Methods[] = {
michael@0 1272 { "width", limage_width },
michael@0 1273 { "height", limage_height },
michael@0 1274 { "__gc", limage_gc },
michael@0 1275 { NULL, NULL }
michael@0 1276 };
michael@0 1277
michael@0 1278 ///////////////////////////////////////////////////////////////////////////////
michael@0 1279
michael@0 1280 static int ltypeface_gc(lua_State* L) {
michael@0 1281 SkSafeUnref(get_ref<SkTypeface>(L, 1));
michael@0 1282 return 0;
michael@0 1283 }
michael@0 1284
michael@0 1285 static const struct luaL_Reg gSkTypeface_Methods[] = {
michael@0 1286 { "__gc", ltypeface_gc },
michael@0 1287 { NULL, NULL }
michael@0 1288 };
michael@0 1289
michael@0 1290 ///////////////////////////////////////////////////////////////////////////////
michael@0 1291
michael@0 1292 class AutoCallLua {
michael@0 1293 public:
michael@0 1294 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
michael@0 1295 lua_getglobal(L, func);
michael@0 1296 if (!lua_isfunction(L, -1)) {
michael@0 1297 int t = lua_type(L, -1);
michael@0 1298 SkDebugf("--- expected function %d\n", t);
michael@0 1299 }
michael@0 1300
michael@0 1301 lua_newtable(L);
michael@0 1302 setfield_string(L, "verb", verb);
michael@0 1303 }
michael@0 1304
michael@0 1305 ~AutoCallLua() {
michael@0 1306 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
michael@0 1307 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
michael@0 1308 }
michael@0 1309 lua_settop(fL, -1);
michael@0 1310 }
michael@0 1311
michael@0 1312 private:
michael@0 1313 lua_State* fL;
michael@0 1314 };
michael@0 1315
michael@0 1316 #define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
michael@0 1317
michael@0 1318 ///////////////////////////////////////////////////////////////////////////////
michael@0 1319
michael@0 1320 static int lsk_newDocumentPDF(lua_State* L) {
michael@0 1321 const char* file = NULL;
michael@0 1322 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
michael@0 1323 file = lua_tolstring(L, 1, NULL);
michael@0 1324 }
michael@0 1325
michael@0 1326 SkDocument* doc = SkDocument::CreatePDF(file);
michael@0 1327 if (NULL == doc) {
michael@0 1328 // do I need to push a nil on the stack and return 1?
michael@0 1329 return 0;
michael@0 1330 } else {
michael@0 1331 push_ref(L, doc);
michael@0 1332 doc->unref();
michael@0 1333 return 1;
michael@0 1334 }
michael@0 1335 }
michael@0 1336
michael@0 1337 static int lsk_newPaint(lua_State* L) {
michael@0 1338 push_new<SkPaint>(L);
michael@0 1339 return 1;
michael@0 1340 }
michael@0 1341
michael@0 1342 static int lsk_newPath(lua_State* L) {
michael@0 1343 push_new<SkPath>(L);
michael@0 1344 return 1;
michael@0 1345 }
michael@0 1346
michael@0 1347 static int lsk_newRRect(lua_State* L) {
michael@0 1348 SkRRect* rr = push_new<SkRRect>(L);
michael@0 1349 rr->setEmpty();
michael@0 1350 return 1;
michael@0 1351 }
michael@0 1352
michael@0 1353 static int lsk_newTypeface(lua_State* L) {
michael@0 1354 const char* name = NULL;
michael@0 1355 int style = SkTypeface::kNormal;
michael@0 1356
michael@0 1357 int count = lua_gettop(L);
michael@0 1358 if (count > 0 && lua_isstring(L, 1)) {
michael@0 1359 name = lua_tolstring(L, 1, NULL);
michael@0 1360 if (count > 1 && lua_isnumber(L, 2)) {
michael@0 1361 style = lua_tointegerx(L, 2, NULL) & SkTypeface::kBoldItalic;
michael@0 1362 }
michael@0 1363 }
michael@0 1364
michael@0 1365 SkTypeface* face = SkTypeface::CreateFromName(name,
michael@0 1366 (SkTypeface::Style)style);
michael@0 1367 // SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
michael@0 1368 if (NULL == face) {
michael@0 1369 face = SkTypeface::RefDefault();
michael@0 1370 }
michael@0 1371 push_ref(L, face);
michael@0 1372 face->unref();
michael@0 1373 return 1;
michael@0 1374 }
michael@0 1375
michael@0 1376 static int lsk_loadImage(lua_State* L) {
michael@0 1377 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
michael@0 1378 const char* name = lua_tolstring(L, 1, NULL);
michael@0 1379 SkAutoDataUnref data(SkData::NewFromFileName(name));
michael@0 1380 if (data.get()) {
michael@0 1381 SkImage* image = SkImage::NewEncodedData(data.get());
michael@0 1382 if (image) {
michael@0 1383 push_ref(L, image);
michael@0 1384 image->unref();
michael@0 1385 return 1;
michael@0 1386 }
michael@0 1387 }
michael@0 1388 }
michael@0 1389 return 0;
michael@0 1390 }
michael@0 1391
michael@0 1392 static void register_Sk(lua_State* L) {
michael@0 1393 lua_newtable(L);
michael@0 1394 lua_pushvalue(L, -1);
michael@0 1395 lua_setglobal(L, "Sk");
michael@0 1396 // the Sk table is still on top
michael@0 1397
michael@0 1398 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
michael@0 1399 setfield_function(L, "loadImage", lsk_loadImage);
michael@0 1400 setfield_function(L, "newPaint", lsk_newPaint);
michael@0 1401 setfield_function(L, "newPath", lsk_newPath);
michael@0 1402 setfield_function(L, "newRRect", lsk_newRRect);
michael@0 1403 setfield_function(L, "newTypeface", lsk_newTypeface);
michael@0 1404 lua_pop(L, 1); // pop off the Sk table
michael@0 1405 }
michael@0 1406
michael@0 1407 #define REG_CLASS(L, C) \
michael@0 1408 do { \
michael@0 1409 luaL_newmetatable(L, get_mtname<C>()); \
michael@0 1410 lua_pushvalue(L, -1); \
michael@0 1411 lua_setfield(L, -2, "__index"); \
michael@0 1412 luaL_setfuncs(L, g##C##_Methods, 0); \
michael@0 1413 lua_pop(L, 1); /* pop off the meta-table */ \
michael@0 1414 } while (0)
michael@0 1415
michael@0 1416 void SkLua::Load(lua_State* L) {
michael@0 1417 register_Sk(L);
michael@0 1418 REG_CLASS(L, SkCanvas);
michael@0 1419 REG_CLASS(L, SkDocument);
michael@0 1420 REG_CLASS(L, SkImage);
michael@0 1421 REG_CLASS(L, SkPath);
michael@0 1422 REG_CLASS(L, SkPaint);
michael@0 1423 REG_CLASS(L, SkRRect);
michael@0 1424 REG_CLASS(L, SkShader);
michael@0 1425 REG_CLASS(L, SkTypeface);
michael@0 1426 REG_CLASS(L, SkMatrix);
michael@0 1427 }
michael@0 1428
michael@0 1429 extern "C" int luaopen_skia(lua_State* L);
michael@0 1430 extern "C" int luaopen_skia(lua_State* L) {
michael@0 1431 SkLua::Load(L);
michael@0 1432 return 0;
michael@0 1433 }

mercurial