]> mj.ucw.cz Git - paperjam.git/commitdiff
Modulo works
authorMartin Mares <mj@ucw.cz>
Sun, 1 Apr 2018 21:18:51 +0000 (23:18 +0200)
committerMartin Mares <mj@ucw.cz>
Sun, 1 Apr 2018 21:18:51 +0000 (23:18 +0200)
cmds.cc
jam.h
paperjam.cc
pdf-tools.cc
pdf-tools.h

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    }
 };
diff --git a/jam.h b/jam.h
index b3f08d78fa3a999dcea5174a8f86566366b8b8a1..b18aa82a4f95f218f23f67479bd2a1e97faa1584 100644 (file)
--- a/jam.h
+++ b/jam.h
@@ -54,6 +54,11 @@ struct page {
   page(double _w=0, double _h=0) : width(_w), height(_h) { }
 };
 
+struct empty_page : public page {
+  void render(page_out *out UNUSED, pdf_matrix xform UNUSED) { }
+  empty_page(double _w=0, double _h=0) : page(_w, _h) { };
+};
+
 struct cmd_exec {
   virtual vector<page *> process(vector <page *> &pages UNUSED) { abort(); }
 };
index f388734bcd9583100f81c7beb9a19a1d738a0c22..0a95acf26abd49b8c06ba2b110bf8703611005af 100644 (file)
@@ -49,28 +49,26 @@ void in_page::render(page_out *out, pdf_matrix xform)
   out->contents += "q " + m.to_string() + " cm " + xobj_res + " Do Q";
 }
 
-static int run_indent;
-
 static void debug_pages(vector<page *> &pages)
 {
   if (!debug_mode)
     return;
 
   for (auto pg: pages)
-    debug("%*sPage #%d: w=%.3f h=%.3f", run_indent, "", pg->index, pg->width, pg->height);
+    debug("Page #%d: w=%.3f h=%.3f", pg->index, pg->width, pg->height);
 }
 
 vector<page *> run_command_list(list<cmd *> &cmds, vector<page *> &pages)
 {
-  debug("%*s# Input", run_indent, "");
+  debug("# Input");
   debug_pages(pages);
 
   for (auto c: cmds)
     {
-      debug("%*s# Executing %s", run_indent, "", c->def->name);
-      run_indent += 4;
+      debug("# Executing %s", c->def->name);
+      debug_indent += 4;
       pages = c->exec->process(pages);
-      run_indent -= 4;
+      debug_indent -= 4;
       debug_pages(pages);
     }
 
index 45f7b56290161c7044fc1f927cacca85aece31e1..9d89ad8153e7d02f3a160346cfea38b5d3718863 100644 (file)
@@ -20,6 +20,7 @@ using namespace std;
 /*** Messages ***/
 
 int debug_mode;
+int debug_indent;
 
 void debug(const char *msg, ...)
 {
@@ -27,6 +28,7 @@ void debug(const char *msg, ...)
                return;
        va_list args;
        va_start(args, msg);
+       fprintf(stderr, "%*s", debug_indent, "");
        vfprintf(stderr, msg, args);
        fputc('\n', stderr);
        va_end(args);
index 98d4b86d48d8cd6671ccc2c0f5540b8622987ef6..a4004d3d8c2e03dccdf9beed4a42bc4202d15875 100644 (file)
@@ -30,6 +30,7 @@ void die(const char *msg, ...) FORMAT_CHECK(printf, 1, 2) NONRET;
 void bad(const char *msg, ...) FORMAT_CHECK(printf, 1, 2) NONRET;
 
 extern int debug_mode;
+extern int debug_indent;
 
 /*** Transformation matrices ***/