/*** null ***/
class null_cmd : public cmd_exec {
- vector<page *> process(vector<page *> pages) { return pages; }
+ vector<page *> process(vector<page *> &pages) { return pages; }
};
-static const arg_def null_args[] = {
+static const arg_def no_args[] = {
{ NULL, 0 }
};
class move_cmd : public cmd_exec {
public:
double x, y;
- vector<page *> process(vector<page *> pages);
+ vector<page *> process(vector<page *> &pages);
};
class xform_page : public page {
orig_page->render(out, xform * parent_xform);
}
-vector<page *> move_cmd::process(vector<page *> pages)
+vector<page *> move_cmd::process(vector<page *> &pages)
{
vector<page *> out;
for (auto p: pages)
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;
}
class scale_cmd : public cmd_exec {
public:
double x_factor, y_factor;
- vector<page *> process(vector<page *> pages);
+ vector<page *> process(vector<page *> &pages);
};
-vector<page *> scale_cmd::process(vector<page *> pages)
+vector<page *> scale_cmd::process(vector<page *> &pages)
{
vector<page *> out;
for (auto p: pages)
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<page *> process(vector<page *> &pages);
+};
+
+vector<page *> rotate_cmd::process(vector<page *> &pages)
+{
+ vector<page *> 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<page *> process(vector<page *> &pages);
+};
+
+static int validate_page_index(vector<page *> &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<page *> select_cmd::process(vector<page *> &pages)
+{
+ vector<page *> 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<page *> 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 }
};