From 3cd34a9be1fce965016122cad0644a2ab3b7ffdd Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 3 Apr 2018 22:51:10 +0200 Subject: [PATCH] Implemented expand, margins --- TODO | 42 ++++++++++++++++++------------------ cmds.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- parse.cc | 9 +++++++- 3 files changed, 91 insertions(+), 25 deletions(-) diff --git a/TODO b/TODO index 5874a01..289e387 100644 --- a/TODO +++ b/TODO @@ -4,30 +4,30 @@ - page->index: use or remove - rename page->bbox to page->image_box? -# Position bbox on a new paper -paper("a4") -paper(w=210mm,h=297mm,pos=(t|b|c)(l|r|c)) +| # Position bbox on a new paper +| paper("a4") +| paper(w=210mm,h=297mm,pos=(t|b|c)(l|r|c)) -# Scale paper to a new size -scaleto("a4") -scaleto(w=210mm,h=297mm,pos=tl) +| # Scale paper to a new size +| scaleto("a4") +| scaleto(w=210mm,h=297mm,pos=tl) -# Fit image to a paper -# If paper is given: scale image -# If no paper is given: adjust paper to image + margins -fit("a4") -fit(w=, h=) -margin= hmargin= vmargin= -lmargin= rmargin= tmargin= bmargin= -pos= +| # Fit image to a paper +| # If paper is given: scale image +| # If no paper is given: adjust paper to image + margins +| fit("a4") +| fit(w=, h=) +| margin= hmargin= vmargin= +| lmargin= rmargin= tmargin= bmargin= +| pos= -# Adjust paper size -expand(10mm) -expand(h=10mm, v=20mm) -expand(l=10mm, r=10mm, t=10mm, b=10mm) +| # Adjust paper size +| expand(10mm) +| expand(h=10mm, v=20mm) +| expand(l=10mm, r=10mm, t=10mm, b=10mm) -# Adjust image size (in terms of margins around) -margins ... params like expand +| # Adjust image size (in terms of margins around) +| margins ... params like expand cropmarks style=box # Box around image @@ -47,7 +47,7 @@ crop duplex long-edge -merge +| merge modulo half diff --git a/cmds.cc b/cmds.cc index 3dcf02b..6acb19c 100644 --- a/cmds.cc +++ b/cmds.cc @@ -209,8 +209,13 @@ public: } }; -#define MARGIN_ARGS(basic, sx) \ - { basic, AT_DIMEN }, \ +#define MARGIN_ARGS1_NAMED(name) \ + { name, AT_DIMEN } + +#define MARGIN_ARGS1_POSNL(name) \ + { name, AT_DIMEN | AT_POSITIONAL } + +#define MARGIN_ARGS2(sx) \ { "h" sx, AT_DIMEN }, \ { "v" sx, AT_DIMEN }, \ { "l" sx, AT_DIMEN }, \ @@ -690,7 +695,59 @@ public: static const arg_def fit_args[] = { PAPER_ARGS, POS_ARGS, - MARGIN_ARGS("margin", "margin"), + MARGIN_ARGS1_NAMED("margin"), + MARGIN_ARGS2("margin"), + { NULL, 0 } +}; + +/*** expand ***/ + +class expand_cmd : public cmd_exec_simple { + margin_spec marg; +public: + expand_cmd(cmd *c) : marg(c, "by", "") { } + page *process_page(page *p) override + { + pdf_matrix xf; + xf.shift(marg.l, marg.b); + page *q = new xform_page(p, 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) + die("Expansion must result in positive page dimensions"); + return q; + } +}; + +static const arg_def expand_args[] = { + MARGIN_ARGS1_POSNL("by"), + MARGIN_ARGS2(""), + { NULL, 0 } +}; + +/*** margins ***/ + +class margins_cmd : public cmd_exec_simple { + margin_spec marg; +public: + margins_cmd(cmd *c) : marg(c, "size", "") { } + page *process_page(page *p) override + { + pdf_matrix xf; + xf.shift(-p->bbox.x_min, -p->bbox.y_min); + xf.shift(marg.l, marg.b); + page *q = new xform_page(p, xf); + q->width = p->bbox.width() + marg.l + marg.r; + q->height = p->bbox.height() + marg.t + marg.b; + if (q->width < 0.001 || q->height < 0.001) + die("Margins must result in positive page dimensions"); + return q; + } +}; + +static const arg_def margins_args[] = { + MARGIN_ARGS1_POSNL("size"), + MARGIN_ARGS2(""), { NULL, 0 } }; @@ -712,5 +769,7 @@ const cmd_def cmd_table[] = { { "paper", paper_args, 0, &ctor }, { "scaleto", scaleto_args, 0, &ctor }, { "fit", fit_args, 0, &ctor }, + { "expand", expand_args, 0, &ctor }, + { "margins", margins_args, 0, &ctor }, { NULL, NULL, 0, NULL } }; diff --git a/parse.cc b/parse.cc index cc0a582..5158eeb 100644 --- a/parse.cc +++ b/parse.cc @@ -218,7 +218,14 @@ static double parse_dimen(const arg_def *adef) t = next_token(); if (t != TOK_IDENT) - parse_error("Parameter %s must have a unit", adef->name); + { + if (is_zero(tmp)) + { + return_token(); + return 0; + } + parse_error("Parameter %s must have a unit", adef->name); + } for (uint i=0; units[i].name; i++) if (token == units[i].name) return tmp * units[i].multiplier; -- 2.39.2