]> mj.ucw.cz Git - paperjam.git/blobdiff - cmds.cc
TODO: a4r paper
[paperjam.git] / cmds.cc
diff --git a/cmds.cc b/cmds.cc
index 3fc12142d10333db5bc53f23be2c19983b6a3f45..a2ac331fca4377cbbf5c427cf7b0af7096b291dc 100644 (file)
--- a/cmds.cc
+++ b/cmds.cc
@@ -1,7 +1,7 @@
 /*
  *     PaperJam -- Commands
  *
- *     (c) 2018 Martin Mares <mj@ucw.cz>
+ *     (c) 2018--2022 Martin Mares <mj@ucw.cz>
  */
 
 #include <cassert>
@@ -25,36 +25,6 @@ static const arg_def no_args[] = {
 
 /*** Generic routines ***/
 
-// Transformed page
-
-class xform_page : public page {
-  page *orig_page;
-  pdf_matrix xform;
-public:
-  void render(out_context *out, pdf_matrix xform) override;
-  xform_page(page *p, pdf_matrix xf);
-};
-
-xform_page::xform_page(page *p, pdf_matrix xf)
-{
-  orig_page = p;
-  index = p->index;
-  xform = xf;
-
-  BBox media(p->width, p->height);
-  media.transform(xf);
-  width = media.width();
-  height = media.height();
-
-  image_box = p->image_box;
-  image_box.transform(xf);
-}
-
-void xform_page::render(out_context *out, pdf_matrix parent_xform)
-{
-  orig_page->render(out, xform * parent_xform);
-}
-
 // Commands acting on individual pages
 
 class cmd_exec_simple : public cmd_exec {
@@ -199,8 +169,8 @@ public:
     {
       bb->x_min += l;
       bb->x_max -= r;
-      bb->y_min += b;
-      bb->y_max -= t;
+      bb->y_min += t;
+      bb->y_max -= b;
       if (bb->x_min >= bb->x_max || bb->y_min >= bb->y_max)
        err("Margins cannot be larger than the whole page");
     }
@@ -208,8 +178,8 @@ public:
     {
       bb->x_min -= l;
       bb->x_max += r;
-      bb->y_min -= b;
-      bb->y_max += t;
+      bb->y_min -= t;
+      bb->y_max += b;
     }
 };
 
@@ -429,7 +399,7 @@ public:
     {
       pdf_matrix m;
       m.shift(x, y);
-      return new xform_page(p, m);
+      return new xform_page(p, "move", m);
     }
 };
 
@@ -453,7 +423,7 @@ public:
     {
       pdf_matrix m;
       m.scale(x_factor, y_factor);
-      return new xform_page(p, m);
+      return new xform_page(p, "scale", m);
     }
 };
 
@@ -478,27 +448,7 @@ public:
     }
   page *process_page(page *p) override
     {
-      pdf_matrix m;
-      switch (deg)
-       {
-       case 0:
-         break;
-       case 90:
-         m.rotate_deg(-90);
-         m.shift(0, p->width);
-         break;
-       case 180:
-         m.rotate_deg(180);
-         m.shift(p->width, p->height);
-         break;
-       case 270:
-         m.rotate_deg(90);
-         m.shift(p->height, 0);
-         break;
-       default:
-         abort();
-       }
-      return new xform_page(p, m);
+      return new xform_page(p, "rotate", pdf_rotation_matrix(deg, p->width, p->height));
     }
 };
 
@@ -533,7 +483,7 @@ public:
          m.scale(-1, 1);
          m.shift(p->width, 0);
        }
-      return new xform_page(p, m);
+      return new xform_page(p, "flip", m);
     }
 };
 
@@ -575,7 +525,7 @@ vector<page *> select_cmd::process(vector<page *> &pages)
          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; i<=t; i += step)
+         for (int i=f; i != t + step; i += step)
            selected.push_back(pages[i]);
        }
       auto processed = run_command_list(pb->commands, selected);
@@ -718,6 +668,11 @@ public:
       out->contents += page_cm->pdf_stream(out, page_bbox, xform);
       out->contents += image_cm->pdf_stream(out, image_box, xform);
     }
+  void debug_dump() override
+    {
+      debug("Draw debugging boxes");
+      orig_page->debug_dump();
+    }
 };
 
 class debug_cmd : public cmd_exec_simple {
@@ -778,6 +733,14 @@ public:
       for (auto p: orig_pages)
        p->render(out, xform);
     }
+  void debug_dump() override
+    {
+      debug("Merge pages");
+      debug_indent += 4;
+      for (auto p: orig_pages)
+       p->debug_dump();
+      debug_indent -= 4;
+    }
 };
 
 vector<page *> merge_cmd::process(vector<page *> &pages)
@@ -799,7 +762,7 @@ public:
     {
       BBox paper_box = BBox(paper.w, paper.h);
       pdf_matrix xf = pos.place(p->image_box, paper_box);
-      page *q = new xform_page(p, xf);
+      page *q = new xform_page(p, "paper", xf);
       q->width = paper.w;
       q->height = paper.h;
       return q;
@@ -827,7 +790,7 @@ public:
       xf.scale(scale_to_fit(orig_box, paper_box));
       orig_box.transform(xf);
       xf.concat(pos.place(orig_box, paper_box));
-      page *q = new xform_page(p, xf);
+      page *q = new xform_page(p, "scaleto", xf);
       q->width = paper.w;
       q->height = paper.h;
       return q;
@@ -862,7 +825,7 @@ public:
          xf.scale(scale_to_fit(orig_box, paper_box));
          orig_box.transform(xf);
          xf.concat(pos.place(orig_box, paper_box));
-         q = new xform_page(p, xf);
+         q = new xform_page(p, "fit", xf);
          q->width = paper.w;
          q->height = paper.h;
        }
@@ -871,7 +834,7 @@ public:
          // No paper given: adjust paper to fit image
          xf.shift(-p->image_box.x_min, -p->image_box.y_min);
          xf.shift(marg.l, marg.b);
-         q = new xform_page(p, xf);
+         q = new xform_page(p, "fit", xf);
          q->width = p->image_box.width() + marg.l + marg.r;
          q->height = p->image_box.height() + marg.t + marg.b;
        }
@@ -897,7 +860,7 @@ public:
     {
       pdf_matrix xf;
       xf.shift(marg.l, marg.b);
-      page *q = new xform_page(p, xf);
+      page *q = new xform_page(p, "expand", xf);
       q->width = p->width + marg.l + marg.r;
       q->height = p->height + marg.t + marg.b;
       if (q->width < 0.001 || q->height < 0.001)
@@ -920,14 +883,10 @@ public:
   margins_cmd(cmd *c) : marg(c, "size", "") { }
   page *process_page(page *p) override
     {
-      pdf_matrix xf;
-      xf.shift(-p->image_box.x_min, -p->image_box.y_min);
-      xf.shift(marg.l, marg.b);
-      page *q = new xform_page(p, xf);
-      q->width = p->image_box.width() + marg.l + marg.r;
-      q->height = p->image_box.height() + marg.t + marg.b;
-      if (q->width < 0.001 || q->height < 0.001)
-       err("Margins must result in positive page dimensions");
+      page *q = new xform_page(p, "margins", pdf_matrix());
+      q->image_box = BBox(marg.l, marg.t, p->width - marg.r, p->height - marg.b);
+      if (q->image_box.width() < 0.001 || q->image_box.height() < 0.001)
+       err("Margins must result in positive image dimensions");
       return q;
     }
 };
@@ -1267,6 +1226,14 @@ public:
   cropmark_spec *cmarks;
   void render(out_context *out, pdf_matrix xform) override;
   nup_page(nup_state &st) : page(st.paper_w, st.paper_h) { }
+  void debug_dump() override
+    {
+      debug("N-up printing");
+      debug_indent += 4;
+      for (auto p: orig_pages)
+       p->debug_dump();
+      debug_indent -= 4;
+    }
 };
 
 void nup_page::render(out_context *out, pdf_matrix parent_xform)
@@ -1364,6 +1331,11 @@ public:
       orig_page->render(out, xform);
       out->contents += cm->pdf_stream(out, image_box, xform);
     }
+  void debug_dump() override
+    {
+      debug("Add cropmarks");
+      orig_page->debug_dump();
+    }
   cropmarks_page(page *p, cropmark_spec *cms) : page(p), orig_page(p), cm(cms) { }
 };
 
@@ -1394,6 +1366,11 @@ public:
       orig_page->render(out, xform);
       out->contents += "Q ";
     }
+  void debug_dump() override
+    {
+      debug("Clip [%.3f %.3f %.3f %.3f]", clip_to.x_min, clip_to.y_min, clip_to.x_max, clip_to.y_max);
+      orig_page->debug_dump();
+    }
   clip_page(page *p, BBox &to) : page(p), orig_page(p), clip_to(to) { }
 };
 
@@ -1437,7 +1414,7 @@ class common_cmd : public cmd_exec {
       vector<page *> out;
       for (auto p: pages)
        {
-         page *q = new xform_page(p, pdf_matrix());
+         page *q = new xform_page(p, "common", pdf_matrix());
          q->width = pbox.width();
          q->height = pbox.height();
          q->image_box = ibox;
@@ -1490,7 +1467,7 @@ vector<page *> slice_cmd::process(vector<page *> &pages)
            pdf_matrix xf = placement;
            xf.shift(-c*pw, -(rows-1-r)*ph);
            xf.shift(margin.l, margin.t);
-           page *q = new xform_page(p, xf);
+           page *q = new xform_page(p, "slice", xf);
            q->width = paper.w;
            q->height = paper.h;
            BBox slice_box = BBox(margin.l, margin.t, paper.w - margin.r, paper.h - margin.b);