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;
}
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);
+ // FIXME: This does not work yet
+ q->xform.rotate_deg(90);
+ 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);
+ return r;
+}
+
/*** Command table ***/
const cmd_def cmd_table[] = {
{ "move", move_args, 0, move_ctor },
{ "scale", scale_args, 0, scale_ctor },
+ { "rotate", rotate_args, 0, rotate_ctor },
{ "null", null_args, 0, null_ctor },
{ NULL, NULL, 0, NULL }
};
enum arg_type {
AT_STRING,
+ AT_INT,
AT_DOUBLE,
AT_DIMEN,
AT_TYPE_MASK = 0xffff,
class arg_val {
public:
virtual bool given() { return false; }
- explicit virtual operator double() { abort(); }
- explicit virtual operator string() { abort(); }
- double double_default(double def) { return given() ? (double) *this : def; }
- const string string_default(const string def) { return given() ? (string) *this : def; }
+ int as_int(int def) { return def; }
+ double as_double(double def) { return def; }
+ const string as_string(const string def) { return def; }
virtual string dump() { return "<undef>"; }
};
/*** Argument types ***/
+class arg_int : public arg_val {
+ int val;
+public:
+ arg_int(int x) { val = x; }
+ bool given() { return true; }
+ int as_int(int def UNUSED) { return val; }
+ string dump() { return to_string(val); }
+};
+
class arg_double : public arg_val {
double val;
public:
- bool given() { return true; }
- explicit operator double () { return val; }
arg_double(double x) { val = x; }
+ bool given() { return true; }
+ double as_double(double def UNUSED) { return val; }
string dump() { return to_string(val); }
};
class arg_string : public arg_val {
string val;
public:
- bool given() { return true; }
- explicit operator string () { return val; }
arg_string(string x) { val = x; }
+ bool given() { return true; }
+ string as_string(string def UNUSED) { return val; }
string dump() { return '"' + val + '"'; }
};
parse_error("Parameter %s must be a string", adef->name);
val = new arg_string(token);
break;
+ case AT_INT:
+ t = next_token();
+ if (t != TOK_NUMBER || !token_is_int())
+ parse_error("Parameter %s must be an integer", adef->name);
+ val = new arg_int((int) token_num);
+ break;
case AT_DOUBLE:
t = next_token();
if (t != TOK_NUMBER)