X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=cmds.cc;h=fa4f615fadeedf28b62aa917422dca6927b4c8f8;hb=d37006564909041ef0a19a99d82c350edcbbdf25;hp=10dd4e0a17d4cc3f40eecd86128f0e6d73da8585;hpb=4f08fc1b75c10b9149e60833fb4deb17f414e0df;p=paperjam.git diff --git a/cmds.cc b/cmds.cc index 10dd4e0..fa4f615 100644 --- a/cmds.cc +++ b/cmds.cc @@ -7,10 +7,10 @@ /*** null ***/ class null_cmd : public cmd_exec { - vector process(vector pages) { return pages; } + vector process(vector &pages) { return pages; } }; -static const arg_def null_args[] = { +static const arg_def no_args[] = { { NULL, 0 } }; @@ -24,7 +24,7 @@ static cmd_exec *null_ctor(cmd *c UNUSED) class move_cmd : public cmd_exec { public: double x, y; - vector process(vector pages); + vector process(vector &pages); }; class xform_page : public page { @@ -40,7 +40,7 @@ void xform_page::render(page_out *out, pdf_matrix parent_xform) orig_page->render(out, xform * parent_xform); } -vector move_cmd::process(vector pages) +vector move_cmd::process(vector &pages) { vector out; for (auto p: pages) @@ -61,8 +61,8 @@ static const arg_def move_args[] = { static cmd_exec *move_ctor(cmd *c) { move_cmd *m = new move_cmd; - m->x = c->args.at(0)->double_default(0); - m->y = c->args.at(1)->double_default(0); + m->x = c->args.at(0)->as_double(0); + m->y = c->args.at(1)->as_double(0); return m; } @@ -71,10 +71,10 @@ static cmd_exec *move_ctor(cmd *c) class scale_cmd : public cmd_exec { public: double x_factor, y_factor; - vector process(vector pages); + vector process(vector &pages); }; -vector scale_cmd::process(vector pages) +vector scale_cmd::process(vector &pages) { vector out; for (auto p: pages) @@ -95,16 +95,119 @@ static const arg_def scale_args[] = { static cmd_exec *scale_ctor(cmd *c) { scale_cmd *s = new scale_cmd; - s->x_factor = c->args.at(0)->double_default(1); - s->y_factor = c->args.at(1)->double_default(s->x_factor); + s->x_factor = c->args.at(0)->as_double(1); + s->y_factor = c->args.at(1)->as_double(s->x_factor); return s; } +/*** rotate ***/ + +class rotate_cmd : public cmd_exec { +public: + int deg; + vector process(vector &pages); +}; + +vector rotate_cmd::process(vector &pages) +{ + vector out; + for (auto p: pages) + { + xform_page *q = new xform_page(p, p->width, p->height); + switch (deg) + { + case 0: + break; + case 90: + q->xform.rotate_deg(-90); + q->xform.shift(0, p->width); + swap(q->width, q->height); + break; + case 180: + q->xform.rotate_deg(180); + q->xform.shift(p->width, p->height); + break; + case 270: + q->xform.rotate_deg(90); + q->xform.shift(p->height, 0); + swap(q->width, q->height); + break; + default: + abort(); + } + out.push_back(q); + } + return out; +} + +static const arg_def rotate_args[] = { + { "angle", AT_INT | AT_MANDATORY | AT_POSITIONAL }, + { NULL, 0 } +}; + +static cmd_exec *rotate_ctor(cmd *c) +{ + rotate_cmd *r = new rotate_cmd; + r->deg = c->args.at(0)->as_int(0) % 360; + if (r->deg < 0) + r->deg += 360; + if (r->deg % 90) + die("Rotate requires a multiple of 90 degrees"); + return r; +} + +/*** select ***/ + +class select_cmd : public cmd_exec { +public: + pipeline *pipe; + vector process(vector &pages); +}; + +static int validate_page_index(vector &pages, int idx) +{ + if (idx >= 1 && idx <= (int) pages.size()) + return idx - 1; + if (idx <= -1 && idx >= (int) -pages.size()) + return idx + pages.size(); + die("Page index %d out of range", idx); +} + +vector select_cmd::process(vector &pages) +{ + vector out; + 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); + int step = (f <= t) ? 1 : -1; + for (int i=f; f<=t; f += step) + { + vector selected; + selected.push_back(pages[i]); + selected = run_command_list(pb->commands, selected); + for (auto p: selected) + out.push_back(p); + } + } + return out; +} + +static cmd_exec *select_ctor(cmd *c) +{ + select_cmd *r = new select_cmd; + r->pipe = c->pipe; + return r; +} + /*** Command table ***/ const cmd_def cmd_table[] = { + { "null", no_args, 0, null_ctor }, { "move", move_args, 0, move_ctor }, { "scale", scale_args, 0, scale_ctor }, - { "null", null_args, 0, null_ctor }, + { "rotate", rotate_args, 0, rotate_ctor }, + { "select", no_args, 1, select_ctor }, { NULL, NULL, 0, NULL } };