Skip to content

Commit a2cc356

Browse files
authored
Require movie canvas dimensions in integer pixels when using modifiers +c|i (#8297)
* Allow dimensions in pixels via movie modifiers +c|i If plot dimensions are given in pixels instead of cm, inches etc then use +c|i to indicate that units the dpu is in since actual plot dimensions is then the pixel dimensions divided by the dpu which gives either cm or inches. * Update movie.c * Check dimensions are integers
1 parent 7868a6a commit a2cc356

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

doc/rst/source/movie.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Synopsis
1313
.. include:: common_SYN_OPTs.rst_
1414

1515
**gmt movie** *mainscript*
16-
|-C|\ *canvas*
16+
|-C|\ *canvassize*
1717
|-N|\ *prefix*
1818
|-T|\ *nframes*\|\ *min*/*max*/*inc*\ [**+n**]\|\ *timefile*\ [**+p**\ *width*]\ [**+s**\ *first*]\ [**+w**\ [*str*]\|\ **W**]
1919
[ |-A|\ *audiofile*\ [**+e**] ]
@@ -73,6 +73,8 @@ Required Arguments
7373
you up to work with the SI or US canvas dimensions. Instead of a named format you can
7474
request a custom format directly by giving *width*\ **x**\ *height*\ **x**\ *dpu*,
7575
where *dpu* is the dots-per-unit pixel density (pixel density is set automatically for the named formats).
76+
Alternatively, give dimensions in pixels and append modifiers **+c** or **+i** to indicate that *dpu* is
77+
per cm or per inches.
7678

7779
.. _tbl-presets:
7880

src/movie.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ struct MOVIE_CTRL {
168168
double duration; /* Original length of audio track */
169169
char *file;
170170
} A;
171-
struct MOVIE_C { /* -C<namedcanvas>|<canvas_and_dpu> */
171+
struct MOVIE_C { /* -C<namedcanvas>|<canvas_and_dpu>[+c|i] */
172172
bool active;
173173
double dim[3];
174174
char unit;
@@ -330,7 +330,7 @@ GMT_LOCAL int movie_parse_x_option (struct GMT_CTRL *GMT, struct MOVIE_CTRL *Ctr
330330
static int usage (struct GMTAPI_CTRL *API, int level) {
331331
const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE);
332332
if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR);
333-
GMT_Usage (API, 0, "usage: %s <mainscript> -C<canvas>|<width>x<height>x<dpu> -N<prefix> -T<nframes>|<min>/<max>/<inc>[+n]|<timefile>[+p<width>][+s<first>][+w[<str>]|W] "
333+
GMT_Usage (API, 0, "usage: %s <mainscript> -C<canvas>|<width>x<height>x<dpu>[+c|i] -N<prefix> -T<nframes>|<min>/<max>/<inc>[+n]|<timefile>[+p<width>][+s<first>][+w[<str>]|W] "
334334
"-A<audiofile>[+e]] [-D<rate>] [-E<titlepage>[+d[<duration>[s]]][+f[i|o][<fade>[s]]][+g<fill>]] [-Fgif|mp4|webm|png[+l[<n>]][+o<opts>][+s<stride>][+t][+v]] "
335335
"[-G[<fill>][+p<pen>]] [-H<scale>] [-I<includefile>] [-K[+f[i|o][<fade>[s]]][+g<fill>][+p[i|o]]] [-L<labelinfo>] [-M[<frame>|f|m|l,][<format>][+r<dpu>][+v]] "
336336
"[-P<progressinfo>] [-Q[s]] [-Sb<background>] [-Sf<foreground>] [%s] [-W[<dir>]] [-Z[s]] [%s] [-x[[-]<n>]] [%s]\n", name, GMT_V_OPT, GMT_f_OPT, GMT_PAR_OPT);
@@ -341,7 +341,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) {
341341

342342
GMT_Usage (API, 1, "\n<mainscript>");
343343
GMT_Usage (API, -2, "<mainscript> is the main GMT modern script that builds a single frame image.");
344-
GMT_Usage (API, 1, "\n-C<canvas>|<width>x<height>x<dpu>");
344+
GMT_Usage (API, 1, "\n-C<canvas>|<width>x<height>x<dpu>[+c|i]");
345345
GMT_Usage (API, -2, "Specify canvas. Choose either a known named canvas or set custom dimensions.");
346346
GMT_Usage (API, -2, "%s Recognized 16:9-ratio names and associated dimensions:", GMT_LINE_BULLET);
347347
/* Using GMT_Message here for verbatim text and alignment since GMT_Usage will eat repeated spaces */
@@ -366,7 +366,9 @@ static int usage (struct GMTAPI_CTRL *API, int level) {
366366
GMT_Usage (API, -2, "Note: uhd-2 and 8k can be used for 4320p, uhd and 4k for 2160p, and fhd or hd for 1080p. "
367367
"Current PROJ_LENGTH_UNIT determines if you get SI or US canvas dimensions and dpu. "
368368
"Alternatively, set a custom canvas with dimensions and dots-per-unit manually by "
369-
"providing <width>x<height>x<dpu> (e.g., 15cx10cx50, 6ix6ix100, etc.).");
369+
"providing <width>x<height>x<dpu> (e.g., 15cx10cx50, 6ix6ix100, etc. Alternatively, give pixel dimensions and a modifier:");
370+
GMT_Usage (API, 3, "+c Dimensions are pixels and dpu is pixels per cm.");
371+
GMT_Usage (API, 3, "+i Dimensions are pixels and dpu is pixels per inch.");
370372
GMT_Usage (API, 1, "\n-N<prefix>");
371373
GMT_Usage (API, -2, "Set the <prefix> used for movie files and directory names. "
372374
"The directory cannot already exist; see -Z to remove such directories at the end.");
@@ -812,8 +814,27 @@ static int parse (struct GMT_CTRL *GMT, struct MOVIE_CTRL *Ctrl, struct GMT_OPTI
812814
else if (!strcmp (arg, "dvd")) { /* 480x640 */
813815
Ctrl->C.dim[GMT_X] = width; Ctrl->C.dim[GMT_Y] = height4x3; Ctrl->C.dim[GMT_Z] = dpu / 6.0;
814816
}
815-
else { /* Custom canvas dimensions */
816-
if ((n = sscanf (arg, "%[^x]x%[^x]x%lg", txt_a, txt_b, &Ctrl->C.dim[GMT_Z])) != 3) {
817+
else { /* Custom canvas dimensions -C<width>[<unit>]x<height>[<unit>]x<dpu>[+c|i] */
818+
if ((c = strstr (arg, "+c"))) /* Got dimensions in dpc units */
819+
c[0] = '\0'; /* Chop off modifier */
820+
else if ((c = strstr (arg, "+i"))) /* Got dimensions in dpi units */
821+
c[0] = '\0'; /* Chop off modifier */
822+
if (c) { /* Got modifier and sides in dpi or dpc -C<width>x<height>x<dpu>[+c|i] */
823+
if ((n = sscanf (arg, "%[^x]x%[^x]x%lg", txt_a, txt_b, &Ctrl->C.dim[GMT_Z])) != 3) {
824+
GMT_Report (API, GMT_MSG_ERROR, "Option -C: Requires dimensions in pixels and either +c or +i for dots per unit\n");
825+
n_errors++;
826+
}
827+
Ctrl->C.dim[GMT_X] = atof (txt_a);
828+
Ctrl->C.dim[GMT_Y] = atof (txt_b);
829+
if (fabs (Ctrl->C.dim[GMT_X] - irint (Ctrl->C.dim[GMT_X])) > 0 || fabs (Ctrl->C.dim[GMT_Y] - irint (Ctrl->C.dim[GMT_Y])) > 0) {
830+
GMT_Report (API, GMT_MSG_ERROR, "Option -C: When either a +c or +i modifier is used, dimensions must be integer pixels\n");
831+
n_errors++;
832+
}
833+
Ctrl->C.dim[GMT_X] = atof (txt_a) / Ctrl->C.dim[GMT_Z];
834+
Ctrl->C.dim[GMT_Y] = atof (txt_b) / Ctrl->C.dim[GMT_Z];
835+
Ctrl->C.unit = c[1]; /* Save inch or cm unit */
836+
}
837+
else if ((n = sscanf (arg, "%[^x]x%[^x]x%lg", txt_a, txt_b, &Ctrl->C.dim[GMT_Z])) != 3) {
817838
GMT_Report (API, GMT_MSG_ERROR, "Option -C: Requires name of a known format or give width x height x dpu string\n");
818839
n_errors++;
819840
}
@@ -1212,7 +1233,7 @@ static int parse (struct GMT_CTRL *GMT, struct MOVIE_CTRL *Ctrl, struct GMT_OPTI
12121233
if (Ctrl->M.active && !Ctrl->F.active[MOVIE_PNG]) Ctrl->M.exit = true; /* Only make the master frame */
12131234

12141235
n_errors += gmt_M_check_condition (GMT, n_files != 1 || Ctrl->In.file == NULL, "Must specify a main script file\n");
1215-
n_errors += gmt_M_check_condition (GMT, !Ctrl->C.active, "Option -C: Must specify a canvas dimension\n");
1236+
n_errors += gmt_M_check_condition (GMT, !Ctrl->C.active, "Option -C: Must specify canvas dimensions\n");
12161237
n_errors += gmt_M_check_condition (GMT, Ctrl->M.exit && Ctrl->animate, "Option -F: Cannot use none with other selections\n");
12171238
n_errors += gmt_M_check_condition (GMT, !Ctrl->Q.active && !Ctrl->M.active && !Ctrl->F.active[MOVIE_PNG], "Must select at least one output product (-F, -M)\n");
12181239
n_errors += gmt_M_check_condition (GMT, Ctrl->Q.active && Ctrl->Z.active, "Cannot use -Z if -Q is also set\n");

0 commit comments

Comments
 (0)