]> mj.ucw.cz Git - paperjam.git/blobdiff - cmds.cc
Modulo works
[paperjam.git] / cmds.cc
diff --git a/cmds.cc b/cmds.cc
index 8a5c0b4434e782a7c30de5d0c90480c30c7d8e3e..61bfd892bb18d0e768f2d5ba76355689fd0dcc4e 100644 (file)
--- a/cmds.cc
+++ b/cmds.cc
@@ -201,6 +201,127 @@ static cmd_exec *select_ctor(cmd *c)
   return r;
 }
 
+/*** apply ***/
+
+class apply_cmd : public cmd_exec {
+public:
+  pipeline *pipe;
+  vector<page *> process(vector<page *> &pages);
+};
+
+static pipeline_branch *find_branch(pipeline *pipe, vector <page *> &pages, int idx)
+{
+  for (auto pb: pipe->branches)
+    for (auto ps: pb->selectors)
+      {
+       int f = validate_page_index(pages, ps.from);
+       int t = validate_page_index(pages, ps.to);
+       if (f <= idx && idx <= t || t <= idx && idx <= f)
+         return pb;
+      }
+  return NULL;
+}
+
+vector<page *> apply_cmd::process(vector<page *> &pages)
+{
+  vector<page *> out;
+
+  int cnt = 0;
+  for (auto p: pages)
+    {
+      pipeline_branch *pb = find_branch(pipe, pages, cnt);
+      if (pb)
+       {
+         vector<page *> tmp;
+         tmp.push_back(p);
+         auto processed = run_command_list(pb->commands, tmp);
+         for (auto q: processed)
+           out.push_back(q);
+       }
+      else
+       out.push_back(p);
+      cnt++;
+    }
+
+  return out;
+}
+
+static cmd_exec *apply_ctor(cmd *c)
+{
+  apply_cmd *r = new apply_cmd;
+  r->pipe = c->pipe;
+  return r;
+}
+
+/*** modulo ***/
+
+class modulo_cmd : public cmd_exec {
+public:
+  pipeline *pipe;
+  int n;
+  vector<page *> process(vector<page *> &pages);
+};
+
+vector<page *> modulo_cmd::process(vector<page *> &pages)
+{
+  vector<page *> out;
+  int tuples = ((int) pages.size() + n - 1) / n;
+
+  for (int tuple=0; tuple < tuples; tuple++)
+    {
+      debug("# Tuple %d", tuple);
+      debug_indent += 4;
+      for (auto pb: pipe->branches)
+       {
+         vector<page *> tmp;
+         for (auto ps: pb->selectors)
+           {
+             int f = ps.from;
+             int t = ps.to;
+             int step = (f <= t) ? 1 : -1;
+             for (int i=f; i<=t; i += step)
+               {
+                 int j;
+                 if (i > 0 && i <= n)
+                   j = tuple*n + i - 1;
+                 else if (i < 0 && i >= -n)
+                   j = (tuples-1-tuple)*n + (-i) - 1;
+                 else
+                   die("Modulo: invalid index %d", i);
+                 if (j < (int) pages.size())
+                   tmp.push_back(pages[j]);
+                 else
+                   {
+                     page *ref_page = pages[tuple*n];
+                     tmp.push_back(new empty_page(ref_page->width, ref_page->height));
+                   }
+               }
+           }
+         auto processed = run_command_list(pb->commands, tmp);
+         for (auto q: processed)
+           out.push_back(q);
+       }
+      debug_indent -= 4;
+    }
+
+  return out;
+}
+
+static const arg_def modulo_args[] = {
+  { "n",       AT_INT | AT_MANDATORY | AT_POSITIONAL },
+  { NULL,      0 }
+};
+
+static cmd_exec *modulo_ctor(cmd *c)
+{
+  modulo_cmd *m = new modulo_cmd;
+  m->n = c->args.at(0)->as_int(0);
+  if (m->n <= 0)
+    die("Modulo must have n > 0");
+  m->pipe = c->pipe;
+  return m;
+}
+
 /*** Command table ***/
 
 const cmd_def cmd_table[] = {
@@ -209,5 +330,7 @@ const cmd_def cmd_table[] = {
   { "scale",   scale_args,     0,      scale_ctor      },
   { "rotate",  rotate_args,    0,      rotate_ctor     },
   { "select",  no_args,        1,      select_ctor     },
+  { "apply",   no_args,        1,      apply_ctor      },
+  { "modulo",  modulo_args,    1,      modulo_ctor     },
   { NULL,      NULL,           0,      NULL    }
 };