From: Martin Mares Date: Sun, 1 Apr 2018 21:18:51 +0000 (+0200) Subject: Modulo works X-Git-Tag: v0.1~39 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=0067f5b7bd14a37261df30bfcd5ca71ed2c1a38a;p=paperjam.git Modulo works --- diff --git a/cmds.cc b/cmds.cc index 8a5c0b4..61bfd89 100644 --- 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 process(vector &pages); +}; + +static pipeline_branch *find_branch(pipeline *pipe, vector &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 apply_cmd::process(vector &pages) +{ + vector out; + + int cnt = 0; + for (auto p: pages) + { + pipeline_branch *pb = find_branch(pipe, pages, cnt); + if (pb) + { + vector 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 process(vector &pages); +}; + +vector modulo_cmd::process(vector &pages) +{ + vector 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 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 b3f08d7..b18aa82 100644 --- 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 process(vector &pages UNUSED) { abort(); } }; diff --git a/paperjam.cc b/paperjam.cc index f388734..0a95acf 100644 --- a/paperjam.cc +++ b/paperjam.cc @@ -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 &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 run_command_list(list &cmds, vector &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); } diff --git a/pdf-tools.cc b/pdf-tools.cc index 45f7b56..9d89ad8 100644 --- a/pdf-tools.cc +++ b/pdf-tools.cc @@ -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); diff --git a/pdf-tools.h b/pdf-tools.h index 98d4b86..a4004d3 100644 --- a/pdf-tools.h +++ b/pdf-tools.h @@ -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 ***/