@@ -1096,6 +1096,9 @@ static int parse (struct GMT_CTRL *GMT, struct PSCONVERT_CTRL *Ctrl, struct GMT_
10961096 n_errors += gmt_M_check_condition (GMT , !Ctrl -> F .active && GMT -> current .setting .run_mode == GMT_MODERN ,
10971097 "Modern GMT mode requires the -F option\n" );
10981098
1099+ n_errors += gmt_M_check_condition (GMT , Ctrl -> O .active && Ctrl -> T .ps && !(GMT_PACKAGE_VERSION_MAJOR > 6 || GMT_PACKAGE_VERSION_MINOR >= 6 ),
1100+ "Insitu modification of PostScript files requires GMT 6.6 or later\n" );
1101+
10991102 return (n_errors ? GMT_PARSE_ERROR : GMT_NOERROR );
11001103}
11011104
@@ -1641,9 +1644,9 @@ EXTERN_MSC int GMT_psconvert(void *V_API, int mode, void *args) {
16411644 size_t len , line_size = 0U , half_baked_size = 0 ;
16421645 uint64_t pos = 0 ;
16431646 bool got_BB , got_HRBB , file_has_HRBB , got_end , landscape , landscape_orig , set_background = false, old_transparency_code_needed ;
1644- bool excessK , setup , found_proj = false, isGMT_PS = false, return_image = false, delete = false, file_processing = true;
1647+ bool excessK , in_BeginSetup , found_proj = false, isGMT_PS = false, return_image = false, delete = false, file_processing = true;
16451648 bool transparency = false, look_for_transparency , BeginPageSetup_here = false, has_transparency , add_grestore = false;
1646- bool first_pagedevice = true, found_EndProlog = false;
1649+ bool first_pagedevice = true, found_EndProlog = false, second_ps = false ;
16471650
16481651 double xt , yt , xt_bak , yt_bak , w , h , x0 = 0.0 , x1 = 612.0 , y0 = 0.0 , y1 = 828.0 ;
16491652 double west = 0.0 , east = 0.0 , south = 0.0 , north = 0.0 ;
@@ -2014,7 +2017,7 @@ EXTERN_MSC int GMT_psconvert(void *V_API, int mode, void *args) {
20142017 file_processing = true; /* Since we now are reading a temporary file */
20152018 }
20162019
2017- got_BB = got_HRBB = file_has_HRBB = got_end = landscape = landscape_orig = setup = false;
2020+ got_BB = got_HRBB = file_has_HRBB = got_end = landscape = landscape_orig = in_BeginSetup = false;
20182021 got_BBatend = 0 ;
20192022
20202023 len = strlen (ps_file );
@@ -2219,12 +2222,12 @@ EXTERN_MSC int GMT_psconvert(void *V_API, int mode, void *args) {
22192222 /* Cannot proceed without knowing the BoundingBox */
22202223
22212224 if (!got_BB ) {
2222- GMT_Report (API , GMT_MSG_ERROR ,
2223- "The file %s has no BoundingBox in the first 20 lines or last 256 bytes. Use -A option.\n" , ps_file );
2225+ GMT_Report (API , GMT_MSG_ERROR ,
2226+ "The file %s has no BoundingBox in the first 20 lines or last 256 bytes. Use -A option.\n" , ps_file );
22242227 if (!Ctrl -> T .eps && gmt_remove_file (GMT , tmp_file )) { /* Remove the temporary EPS file */
2225- if (fp != NULL ) fclose (fp );
2226- if (fp2 != NULL ) fclose (fp2 );
2227- if (fpo != NULL ) fclose (fpo );
2228+ if (fp != NULL ) fclose (fp );
2229+ if (fp2 != NULL ) fclose (fp2 );
2230+ if (fpo != NULL ) fclose (fpo );
22282231 Return (GMT_RUNTIME_ERROR );
22292232 }
22302233 continue ;
@@ -2280,29 +2283,58 @@ EXTERN_MSC int GMT_psconvert(void *V_API, int mode, void *args) {
22802283 look_for_transparency = false; /* No need to check anymore */
22812284 }
22822285
2283- if (setup && Ctrl -> T .ps != 1 && strstr (line ,"setpagedevice" ) != NULL ) { /* This is a "setpagedevice" command that should be avoided */
2284- if (Ctrl -> O .active ) {
2285- size_t len = strlen (line );
2286- fseek (fp , (off_t )- (len + 1 ), SEEK_CUR ); /* Seek back to start of line (+1 why?) */
2287- if (first_pagedevice ) { /* Some files have 1, others have 2 occurences of 'setpagedevice' */
2288- if (r != 0 ) { /* Rotations must come before translations */
2289- char t [GMT_LEN64 ] = "" ; /* To hold the translation string */
2290- sprintf (line , "%d rotate\n" , r ); /* Now 'line' has new length */
2291- sprintf (t , "%g %g translate" , xt , yt );
2292- strcat (line , t );
2293- for (int i = strlen (line )+ strlen (t ); i < len ; i ++ ) line [i ] = ' ' ; /* Fill remainings with spaces */
2286+ if (in_BeginSetup && strstr (line ,"setpagedevice" ) != NULL ) { /* This is a "setpagedevice" command that should be avoided */
2287+ if (Ctrl -> T .ps != 1 ) { /* Not PS */
2288+ if (Ctrl -> O .active ) {
2289+ size_t len = strlen (line );
2290+ fseek (fp , (off_t )- (len + 1 ), SEEK_CUR ); /* Seek back to start of line (+1 why?) */
2291+ if (first_pagedevice ) { /* Some files have 1, others have 2 occurences of 'setpagedevice' */
2292+ if (r != 0 ) { /* Rotations must come before translations */
2293+ char t [GMT_LEN64 ] = "" ; /* To hold the translation string */
2294+ sprintf (line , "%d rotate\n" , r ); /* Now 'line' has new length */
2295+ sprintf (t , "%g %g translate" , xt , yt );
2296+ strcat (line , t );
2297+ for (int i = strlen (line )+ strlen (t ); i < len ; i ++ ) line [i ] = ' ' ; /* Fill remainings with spaces */
2298+ }
2299+ else
2300+ sprintf (line , "%g %g translate" , xt , yt );
2301+
2302+ first_pagedevice = false;
22942303 }
22952304 else
2296- sprintf ( line , "%g %g translate" , xt , yt ) ;
2305+ for ( int i = 0 ; i < len ; i ++ ) line [ i ] = ' ' ;
22972306
2298- first_pagedevice = false ;
2307+ fprintf ( fp , "%s" , line ); fflush ( fp ) ;
22992308 }
2300- else
2301- for (int i = 0 ; i < len ; i ++ ) line [i ] = ' ' ;
2309+ continue ;
2310+ }
2311+ else { /* Resquested a PS output. Soo keep the setpagedevice but adjust the PageSize. */
2312+ if (Ctrl -> O .active ) {
2313+ size_t len = strlen (line );
2314+ if (strstr (line ,"PageSize" ) == NULL ) continue ; /* The other "setpagedevice" command. Too keep as is. */
2315+ fseek (fp , (off_t )- (len + 1 ), SEEK_CUR ); /* Seek back to start of line */
2316+ sprintf (line , "PSLevel 1 gt { << /PageSize [%.7g %.7g] /ImagingBBox null >> setpagedevice } if" , x1 - x0 , y1 - y0 );
2317+ for (int i = strlen (line ); i < len ; i ++ ) line [i ] = ' ' ; /* Fill remainings with spaces */
2318+ fprintf (fp , "%s" , line ); fflush (fp );
2319+
2320+ psconvert_file_line_reader (GMT , & line , & line_size , fp ); /* Read the next line */
2321+ n_read_PS_lines ++ ;
2322+ fseek (fp , (off_t )- (strlen (line ) + 1 ), SEEK_CUR );
2323+ if (r != 0 ) { /* Rotations must come before translations */
2324+ char t [GMT_LEN32 ] = "" ; /* To hold the translation string */
2325+ sprintf (line , "%d R\n" , r ); /* Now 'line' has new length */
2326+ sprintf (t , "%g %g T" , xt , yt );
2327+ strcat (line , t );
2328+ }
2329+ else
2330+ sprintf (line , "%g %g T" , xt , yt );
23022331
2303- fprintf (fp , "%s" , line ); fflush (fp );
2332+ fprintf (fp , "%s" , line ); fflush (fp );
2333+ continue ;
2334+ }
2335+ else if (strstr (line ,"PageSize" ) != NULL )
2336+ sprintf (line , "PSLevel 1 gt { << /PageSize [%.7g %.7g] /ImagingBBox null >> setpagedevice } if" , x1 - x0 , y1 - y0 );
23042337 }
2305- continue ;
23062338 }
23072339
23082340 if (old_transparency_code_needed && strstr (line , ".setfillconstantalpha" )) {
@@ -2420,9 +2452,9 @@ EXTERN_MSC int GMT_psconvert(void *V_API, int mode, void *args) {
24202452 continue ;
24212453 }
24222454 else if (!strncmp (line , "%%BeginSetup" , 12 ))
2423- setup = true;
2455+ in_BeginSetup = true;
24242456 else if (!strncmp (line , "%%EndSetup" , 10 )) {
2425- setup = false;
2457+ in_BeginSetup = false;
24262458 if (Ctrl -> T .eps == -1 ) /* -TE option. Write out setpagedevice command. Note: The -! option cannot be active here. */
24272459 fprintf (fpo , "<< /PageSize [%g %g] >> setpagedevice\n" , w , h );
24282460 if (r != 0 )
@@ -2613,6 +2645,15 @@ EXTERN_MSC int GMT_psconvert(void *V_API, int mode, void *args) {
26132645 fclose (fpo ); fpo = NULL ;
26142646 fclose (fp ); fp = NULL ;
26152647
2648+ if (!Ctrl -> O .active && Ctrl -> T .ps && GMT -> current .setting .run_mode == GMT_CLASSIC ) {
2649+ second_ps = true; /* Tell the renaming branch of modern mode to deal with this case too */
2650+ if (!Ctrl -> F .file ) {
2651+ size_t len = strlen (ps_file );
2652+ Ctrl -> F .file = strdup (ps_file );
2653+ Ctrl -> F .file [len - 3 ] = '_' ; /* Change the last ".ps" to "_2" */
2654+ Ctrl -> F .file [len - 2 ] = '2' ; Ctrl -> F .file [len - 1 ] = '\0' ;
2655+ }
2656+ }
26162657
26172658 if (has_transparency && gsVersion .major == 9 && (gsVersion .minor == 51 || gsVersion .minor == 52 ))
26182659 GMT_Report (API , GMT_MSG_WARNING , "Input file has transparency but your gs version %s has a bug preventing it - please upgrade to 9.53 or later\n" , GSstring );
@@ -2639,7 +2680,7 @@ EXTERN_MSC int GMT_psconvert(void *V_API, int mode, void *args) {
26392680 strcat (out_file , "_intermediate" );
26402681 }
26412682 else { /* Output is the final result */
2642- GMT_Report (API , GMT_MSG_INFORMATION , "Convert to %s...\n" , tag );
2683+ GMT_Report (API , GMT_MSG_INFORMATION , "Convert to %s...\n" , tag );
26432684
26442685 if (Ctrl -> D .active ) sprintf (out_file , "%s/" , Ctrl -> D .dir ); /* Use specified output directory */
26452686 if (!Ctrl -> F .active || return_image )
@@ -2743,7 +2784,7 @@ EXTERN_MSC int GMT_psconvert(void *V_API, int mode, void *args) {
27432784 }
27442785 }
27452786
2746- if (GMT -> current .setting .run_mode == GMT_MODERN ) {
2787+ if (GMT -> current .setting .run_mode == GMT_MODERN || second_ps ) { /* Modern mode or -Tp where we also want to save the XXX.eps as a ps file */
27472788 if (Ctrl -> T .ps ) { /* Under modern mode we can also save the PS file by renaming it */
27482789 out_file [0 ] = '\0' ; /* truncate string to build new output file */
27492790 if (Ctrl -> D .active ) sprintf (out_file , "%s/" , Ctrl -> D .dir ); /* Use specified output directory */
0 commit comments