]> mj.ucw.cz Git - paperjam.git/commitdiff
Flip and switch parameters
authorMartin Mares <mj@ucw.cz>
Mon, 2 Apr 2018 09:05:33 +0000 (11:05 +0200)
committerMartin Mares <mj@ucw.cz>
Mon, 2 Apr 2018 09:05:33 +0000 (11:05 +0200)
cmds.cc
jam.h
parse.cc

diff --git a/cmds.cc b/cmds.cc
index 24fb0a4d4bb038ad277d17f76e72d64ac7f19a66..ca3f81ff76f55d990291544e112016b41a42c9a6 100644 (file)
--- a/cmds.cc
+++ b/cmds.cc
@@ -171,6 +171,52 @@ static cmd_exec *rotate_ctor(cmd *c)
   return r;
 }
 
+/*** flip ***/
+
+class flip_cmd : public cmd_exec {
+public:
+  bool horizontal;
+  bool vertical;
+  vector<page *> process(vector<page *> &pages);
+};
+
+vector<page *> flip_cmd::process(vector<page *> &pages)
+{
+  vector<page *> out;
+  for (auto p: pages)
+    {
+      pdf_matrix m;
+      if (vertical)
+       {
+         m.scale(1, -1);
+         m.shift(0, p->height);
+       }
+      if (horizontal)
+       {
+         m.scale(-1, 1);
+         m.shift(p->width, 0);
+       }
+      out.push_back(new xform_page(p, m));
+    }
+  return out;
+}
+
+static const arg_def flip_args[] = {
+  { "h",       AT_SWITCH },
+  { "v",       AT_SWITCH },
+  { NULL,      0 }
+};
+
+static cmd_exec *flip_ctor(cmd *c)
+{
+  flip_cmd *f = new flip_cmd;
+  f->horizontal = c->args.at(0)->as_int(0);
+  f->vertical = c->args.at(1)->as_int(0);
+  if (!f->horizontal && !f->vertical)
+    die("Flip has no direction specified");
+  return f;
+}
+
 /*** select ***/
 
 class select_cmd : public cmd_exec {
@@ -383,6 +429,7 @@ const cmd_def cmd_table[] = {
   { "move",    move_args,      0,      move_ctor       },
   { "scale",   scale_args,     0,      scale_ctor      },
   { "rotate",  rotate_args,    0,      rotate_ctor     },
+  { "flip",    flip_args,      0,      flip_ctor       },
   { "select",  no_args,        1,      select_ctor     },
   { "apply",   no_args,        1,      apply_ctor      },
   { "modulo",  modulo_args,    1,      modulo_ctor     },
diff --git a/jam.h b/jam.h
index a966cea36d72bce230f9b775284f190ef8ef05eb..002ad04b831d1f11b17884448a0c0ea721e4fb71 100644 (file)
--- a/jam.h
+++ b/jam.h
@@ -18,6 +18,7 @@ enum arg_type {
   AT_INT,
   AT_DOUBLE,
   AT_DIMEN,
+  AT_SWITCH,
   AT_TYPE_MASK = 0xffff,
   AT_MANDATORY = 0x10000,
   AT_POSITIONAL = 0x20000,
index 1869b3a76ef04345ffd4d0ead54f7bbe2314eba6..d3d92cd083df81a98bef9f263b85869bcb46b992 100644 (file)
--- a/parse.cc
+++ b/parse.cc
@@ -295,7 +295,10 @@ static void parse_args(cmd *c)
   for (;;)
     {
       t = next_token();
+      if (t == TOK_CLOSE_PAREN)
+        break;
       uint argi = 0;
+      bool has_value = false;
       if (t == TOK_IDENT)
        {
          while (adefs[argi].name && token != adefs[argi].name)
@@ -305,8 +308,10 @@ static void parse_args(cmd *c)
          if (c->args.at(argi)->given())
            parse_error("Parameter %s given multiple times", token.c_str());
          t = next_token();
-         if (t != TOK_EQUAL)
-           parse_error("Parameter name must be followed by '='");
+         if (t == TOK_EQUAL)
+           has_value = true;
+         else
+           return_token();
          saw_named = true;
        }
       else if (saw_named)
@@ -319,35 +324,53 @@ static void parse_args(cmd *c)
          if (next_pos >= num_args)
            parse_error("Too many positional arguments for command %s", cdef->name);
          argi = next_pos++;
+         has_value = true;
        }
 
       const arg_def *adef = &adefs[argi];
+      uint type = adef->type & AT_TYPE_MASK;
       arg_val *val = NULL;
-      switch (adef->type & AT_TYPE_MASK)
-       {
-       case AT_STRING:
-         t = next_token();
-         if (t != TOK_STRING)
-           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)
-           parse_error("Parameter %s must be a number", adef->name);
-         val = new arg_double(token_num);
-         break;
-       case AT_DIMEN:
-         val = new arg_double(parse_dimen(adef));
-         break;
-       default:
-         abort();
+      if (has_value)
+        {
+         switch (type)
+           {
+           case AT_STRING:
+             t = next_token();
+             if (t != TOK_STRING)
+               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)
+               parse_error("Parameter %s must be a number", adef->name);
+             val = new arg_double(token_num);
+             break;
+           case AT_DIMEN:
+             val = new arg_double(parse_dimen(adef));
+             break;
+           case AT_SWITCH:
+             t = next_token();
+             if (t != TOK_NUMBER || !token_is_int() || ((int) token_num != 0 && (int) token_num != 1))
+               parse_error("Parameter %s must be a switch", adef->name);
+             val = new arg_int((int) token_num);
+             break;
+           default:
+             abort();
+           }
+       }
+      else
+        {
+         if (type == AT_SWITCH)
+           val = new arg_int(1);
+         else
+           parse_error("Parameter %s must have a value", adef->name);
        }
 
       c->args.at(argi) = val;
@@ -469,7 +492,7 @@ void help()
 
       const arg_def *arg = def->arg_defs;
       static const char * const type_names[] = {
-       "string", "int", "double", "dimen"
+       "string", "int", "double", "dimen", "switch"
       };
       while (arg->name)
        {