lua_pictures.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  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. #include "include/core/SkData.h"
  8. #include "include/core/SkGraphics.h"
  9. #include "include/core/SkPicture.h"
  10. #include "include/core/SkStream.h"
  11. #include "include/utils/SkLua.h"
  12. #include "include/utils/SkLuaCanvas.h"
  13. #include "src/core/SkOSFile.h"
  14. #include "src/utils/SkOSPath.h"
  15. #include "tools/flags/CommandLineFlags.h"
  16. #include <stdlib.h>
  17. extern "C" {
  18. #include "lua.h"
  19. #include "lualib.h"
  20. #include "lauxlib.h"
  21. }
  22. static const char gStartCanvasFunc[] = "sk_scrape_startcanvas";
  23. static const char gEndCanvasFunc[] = "sk_scrape_endcanvas";
  24. static const char gAccumulateFunc[] = "sk_scrape_accumulate";
  25. static const char gSummarizeFunc[] = "sk_scrape_summarize";
  26. // Example usage for the modulo flag:
  27. // for i in {0..5}; do lua_pictures --skpPath SKP_PATH -l YOUR_SCRIPT --modulo $i 6 &; done
  28. static DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which "
  29. "testIndex %% divisor == remainder.");
  30. static DEFINE_string2(skpPath, r, "", "Read this .skp file or .skp files from this dir");
  31. static DEFINE_string2(luaFile, l, "", "File containing lua script to run");
  32. static DEFINE_string2(headCode, s, "", "Optional lua code to call at beginning");
  33. static DEFINE_string2(tailFunc, s, "", "Optional lua function to call at end");
  34. static DEFINE_bool2(quiet, q, false, "Silence all non-error related output");
  35. static sk_sp<SkPicture> load_picture(const char path[]) {
  36. std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(path);
  37. if (stream) {
  38. return SkPicture::MakeFromStream(stream.get());
  39. }
  40. return nullptr;
  41. }
  42. static void call_canvas(lua_State* L, SkLuaCanvas* canvas,
  43. const char pictureFile[], const char funcName[]) {
  44. lua_getglobal(L, funcName);
  45. if (!lua_isfunction(L, -1)) {
  46. int t = lua_type(L, -1);
  47. SkDebugf("--- expected %s function %d, ignoring.\n", funcName, t);
  48. lua_settop(L, -2);
  49. } else {
  50. canvas->pushThis();
  51. lua_pushstring(L, pictureFile);
  52. if (lua_pcall(L, 2, 0, 0) != LUA_OK) {
  53. SkDebugf("lua err: %s\n", lua_tostring(L, -1));
  54. }
  55. }
  56. }
  57. int main(int argc, char** argv) {
  58. CommandLineFlags::SetUsage("apply lua script to .skp files.");
  59. CommandLineFlags::Parse(argc, argv);
  60. if (FLAGS_skpPath.isEmpty()) {
  61. SkDebugf(".skp files or directories are required.\n");
  62. exit(-1);
  63. }
  64. if (FLAGS_luaFile.isEmpty()) {
  65. SkDebugf("missing luaFile(s)\n");
  66. exit(-1);
  67. }
  68. const char* summary = gSummarizeFunc;
  69. if (!FLAGS_tailFunc.isEmpty()) {
  70. summary = FLAGS_tailFunc[0];
  71. }
  72. SkAutoGraphics ag;
  73. SkLua L(summary);
  74. for (int i = 0; i < FLAGS_luaFile.count(); ++i) {
  75. sk_sp<SkData> data(SkData::MakeFromFileName(FLAGS_luaFile[i]));
  76. if (!data) {
  77. data = SkData::MakeEmpty();
  78. }
  79. if (!FLAGS_quiet) {
  80. SkDebugf("loading %s...\n", FLAGS_luaFile[i]);
  81. }
  82. if (!L.runCode(data->data(), data->size())) {
  83. SkDebugf("failed to load luaFile %s\n", FLAGS_luaFile[i]);
  84. exit(-1);
  85. }
  86. }
  87. if (!FLAGS_headCode.isEmpty()) {
  88. L.runCode(FLAGS_headCode[0]);
  89. }
  90. int moduloRemainder = -1;
  91. int moduloDivisor = -1;
  92. SkString moduloStr;
  93. if (FLAGS_modulo.count() == 2) {
  94. moduloRemainder = atoi(FLAGS_modulo[0]);
  95. moduloDivisor = atoi(FLAGS_modulo[1]);
  96. if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= moduloDivisor) {
  97. SkDebugf("invalid modulo values.\n");
  98. return -1;
  99. }
  100. }
  101. for (int i = 0; i < FLAGS_skpPath.count(); i ++) {
  102. SkTArray<SkString> paths;
  103. if (sk_isdir(FLAGS_skpPath[i])) {
  104. // Add all .skp in this directory.
  105. const SkString directory(FLAGS_skpPath[i]);
  106. SkString filename;
  107. SkOSFile::Iter iter(FLAGS_skpPath[i], "skp");
  108. while(iter.next(&filename)) {
  109. paths.push_back() = SkOSPath::Join(directory.c_str(), filename.c_str());
  110. }
  111. } else {
  112. // Add this as an .skp itself.
  113. paths.push_back() = FLAGS_skpPath[i];
  114. }
  115. for (int i = 0; i < paths.count(); i++) {
  116. if (moduloRemainder >= 0) {
  117. if ((i % moduloDivisor) != moduloRemainder) {
  118. continue;
  119. }
  120. moduloStr.printf("[%d.%d] ", i, moduloDivisor);
  121. }
  122. const char* path = paths[i].c_str();
  123. if (!FLAGS_quiet) {
  124. SkDebugf("scraping %s %s\n", path, moduloStr.c_str());
  125. }
  126. auto pic(load_picture(path));
  127. if (pic.get()) {
  128. std::unique_ptr<SkLuaCanvas> canvas(
  129. new SkLuaCanvas(SkScalarCeilToInt(pic->cullRect().width()),
  130. SkScalarCeilToInt(pic->cullRect().height()),
  131. L.get(), gAccumulateFunc));
  132. call_canvas(L.get(), canvas.get(), path, gStartCanvasFunc);
  133. canvas->drawPicture(pic);
  134. call_canvas(L.get(), canvas.get(), path, gEndCanvasFunc);
  135. } else {
  136. SkDebugf("failed to load\n");
  137. }
  138. }
  139. }
  140. return 0;
  141. }