+/*** slice ***/
+
+class slice_cmd : public cmd_exec {
+ paper_spec paper;
+ pos_spec pos;
+ margin_spec margin;
+ double bleed;
+public:
+ slice_cmd(cmd *c) : paper(c), pos(c), margin(c, "margin", "margin")
+ {
+ if (is_zero(paper.w) || is_zero(paper.h))
+ err("Paper format must be given");
+ bleed = c->arg("bleed")->as_double(0);
+ }
+ vector<page *> process(vector<page *> &pages) override;
+};
+
+vector<page *> slice_cmd::process(vector<page *> &pages)
+{
+ vector<page *> out;
+
+ for (auto p: pages)
+ {
+ double pw = paper.w - margin.l - margin.r;
+ double ph = paper.h - margin.t - margin.b;
+ if (pw < 0 || ph < 0)
+ err("Margins larger than paper");
+
+ int cols = (int) ceil((p->image_box.width() - 2*mm) / pw);
+ int rows = (int) ceil((p->image_box.height() - 2*mm) / ph);
+ BBox big_box(cols*pw, rows*ph);
+ pdf_matrix placement = pos.place(p->image_box, big_box);
+
+ debug("Slicing [%.3f,%.3f] to %dx%d [%.3f,%.3f]", p->image_box.width(), p->image_box.height(), rows, cols, pw, ph);
+ for (int r=0; r<rows; r++)
+ for (int c=0; c<cols; c++)
+ {
+ 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);
+ q->width = paper.w;
+ q->height = paper.h;
+ BBox slice_box = BBox(margin.l, margin.t, paper.w - margin.r, paper.h - margin.b);
+ q->image_box = p->image_box.transformed(xf);
+ q->image_box.intersect(slice_box);
+ BBox bleeding_slice = slice_box.enlarged(bleed);
+ out.push_back(new clip_page(q, bleeding_slice));
+ }
+ }
+
+ return out;
+}
+
+static const arg_def slice_args[] = {
+ PAPER_ARGS,
+ POS_ARGS,
+ MARGIN_ARGS1_NAMED("margin"),
+ MARGIN_ARGS2("margin"),
+ { "bleed", AT_DIMEN, "Allow bleeding of image outside its box" },
+ { NULL, 0, NULL }
+};
+