diff --git a/doc/rst/source/movie.rst b/doc/rst/source/movie.rst index 5540bf5c7b5..260e06f23ff 100644 --- a/doc/rst/source/movie.rst +++ b/doc/rst/source/movie.rst @@ -13,7 +13,7 @@ Synopsis .. include:: common_SYN_OPTs.rst_ **gmt movie** *mainscript* -|-C|\ *canvas* +|-C|\ *canvassize* |-N|\ *prefix* |-T|\ *nframes*\|\ *min*/*max*/*inc*\ [**+n**]\|\ *timefile*\ [**+p**\ *width*]\ [**+s**\ *first*]\ [**+w**\ [*str*]\|\ **W**] [ |-A|\ *audiofile*\ [**+e**] ] @@ -73,6 +73,8 @@ Required Arguments you up to work with the SI or US canvas dimensions. Instead of a named format you can request a custom format directly by giving *width*\ **x**\ *height*\ **x**\ *dpu*, where *dpu* is the dots-per-unit pixel density (pixel density is set automatically for the named formats). + Alternatively, give dimensions in pixels and append modifiers **+c** or **+i** to indicate that *dpu* is + per cm or per inches. .. _tbl-presets: diff --git a/src/movie.c b/src/movie.c index 45b1b396546..d744bcc593d 100644 --- a/src/movie.c +++ b/src/movie.c @@ -168,7 +168,7 @@ struct MOVIE_CTRL { double duration; /* Original length of audio track */ char *file; } A; - struct MOVIE_C { /* -C| */ + struct MOVIE_C { /* -C|[+c|i] */ bool active; double dim[3]; char unit; @@ -330,7 +330,7 @@ GMT_LOCAL int movie_parse_x_option (struct GMT_CTRL *GMT, struct MOVIE_CTRL *Ctr static int usage (struct GMTAPI_CTRL *API, int level) { const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE); if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR); - GMT_Usage (API, 0, "usage: %s -C|xx -N -T|//[+n]|[+p][+s][+w[]|W] " + GMT_Usage (API, 0, "usage: %s -C|xx[+c|i] -N -T|//[+n]|[+p][+s][+w[]|W] " "-A[+e]] [-D] [-E[+d[[s]]][+f[i|o][[s]]][+g]] [-Fgif|mp4|webm|png[+l[]][+o][+s][+t][+v]] " "[-G[][+p]] [-H] [-I] [-K[+f[i|o][[s]]][+g][+p[i|o]]] [-L] [-M[|f|m|l,][][+r][+v]] " "[-P] [-Q[s]] [-Sb] [-Sf] [%s] [-W[]] [-Z[s]] [%s] [-x[[-]]] [%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) { GMT_Usage (API, 1, "\n"); GMT_Usage (API, -2, " is the main GMT modern script that builds a single frame image."); - GMT_Usage (API, 1, "\n-C|xx"); + GMT_Usage (API, 1, "\n-C|xx[+c|i]"); GMT_Usage (API, -2, "Specify canvas. Choose either a known named canvas or set custom dimensions."); GMT_Usage (API, -2, "%s Recognized 16:9-ratio names and associated dimensions:", GMT_LINE_BULLET); /* 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) { 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. " "Current PROJ_LENGTH_UNIT determines if you get SI or US canvas dimensions and dpu. " "Alternatively, set a custom canvas with dimensions and dots-per-unit manually by " - "providing xx (e.g., 15cx10cx50, 6ix6ix100, etc.)."); + "providing xx (e.g., 15cx10cx50, 6ix6ix100, etc. Alternatively, give pixel dimensions and a modifier:"); + GMT_Usage (API, 3, "+c Dimensions are pixels and dpu is pixels per cm."); + GMT_Usage (API, 3, "+i Dimensions are pixels and dpu is pixels per inch."); GMT_Usage (API, 1, "\n-N"); GMT_Usage (API, -2, "Set the used for movie files and directory names. " "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 else if (!strcmp (arg, "dvd")) { /* 480x640 */ Ctrl->C.dim[GMT_X] = width; Ctrl->C.dim[GMT_Y] = height4x3; Ctrl->C.dim[GMT_Z] = dpu / 6.0; } - else { /* Custom canvas dimensions */ - if ((n = sscanf (arg, "%[^x]x%[^x]x%lg", txt_a, txt_b, &Ctrl->C.dim[GMT_Z])) != 3) { + else { /* Custom canvas dimensions -C[]x[]x[+c|i] */ + if ((c = strstr (arg, "+c"))) /* Got dimensions in dpc units */ + c[0] = '\0'; /* Chop off modifier */ + else if ((c = strstr (arg, "+i"))) /* Got dimensions in dpi units */ + c[0] = '\0'; /* Chop off modifier */ + if (c) { /* Got modifier and sides in dpi or dpc -Cxx[+c|i] */ + if ((n = sscanf (arg, "%[^x]x%[^x]x%lg", txt_a, txt_b, &Ctrl->C.dim[GMT_Z])) != 3) { + GMT_Report (API, GMT_MSG_ERROR, "Option -C: Requires dimensions in pixels and either +c or +i for dots per unit\n"); + n_errors++; + } + Ctrl->C.dim[GMT_X] = atof (txt_a); + Ctrl->C.dim[GMT_Y] = atof (txt_b); + 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) { + GMT_Report (API, GMT_MSG_ERROR, "Option -C: When either a +c or +i modifier is used, dimensions must be integer pixels\n"); + n_errors++; + } + Ctrl->C.dim[GMT_X] = atof (txt_a) / Ctrl->C.dim[GMT_Z]; + Ctrl->C.dim[GMT_Y] = atof (txt_b) / Ctrl->C.dim[GMT_Z]; + Ctrl->C.unit = c[1]; /* Save inch or cm unit */ + } + else if ((n = sscanf (arg, "%[^x]x%[^x]x%lg", txt_a, txt_b, &Ctrl->C.dim[GMT_Z])) != 3) { GMT_Report (API, GMT_MSG_ERROR, "Option -C: Requires name of a known format or give width x height x dpu string\n"); n_errors++; } @@ -1212,7 +1233,7 @@ static int parse (struct GMT_CTRL *GMT, struct MOVIE_CTRL *Ctrl, struct GMT_OPTI if (Ctrl->M.active && !Ctrl->F.active[MOVIE_PNG]) Ctrl->M.exit = true; /* Only make the master frame */ n_errors += gmt_M_check_condition (GMT, n_files != 1 || Ctrl->In.file == NULL, "Must specify a main script file\n"); - n_errors += gmt_M_check_condition (GMT, !Ctrl->C.active, "Option -C: Must specify a canvas dimension\n"); + n_errors += gmt_M_check_condition (GMT, !Ctrl->C.active, "Option -C: Must specify canvas dimensions\n"); n_errors += gmt_M_check_condition (GMT, Ctrl->M.exit && Ctrl->animate, "Option -F: Cannot use none with other selections\n"); 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"); n_errors += gmt_M_check_condition (GMT, Ctrl->Q.active && Ctrl->Z.active, "Cannot use -Z if -Q is also set\n");