#include <fstream.h> #include <strstream.h> #include <stdio.h> /* ANSI: utility functions */ #include <stdlib.h> /* ANSI: utility functions */ #include <string.h> /* ANSI: string operations */ //----- string constants const char VERSION[] = "1.0"; const char EPS_HEADER[] = "%!PS-Adobe-3.0 EPSF-3.0"; const char EPS_BOUNDING_BOX[] = "%%BoundingBox:"; const int LENGTH_EPS_BOUNDING_BOX = strlen( EPS_BOUNDING_BOX ) ; //----- point / mm const double ptOverMm = 72.0 / 25.4 ; //----- A4 size (mm) const double A4_WIDTH = 210.0 ; // mm const double A4_HEIGHT = 297.0 ; // mm //----- A4 size (pt) const double A4_WIDTH_pt = A4_WIDTH * ptOverMm ; const double A4_HEIGHT_pt = A4_HEIGHT * ptOverMm ; //----- size of DAWN picture (mm) const double DAWN_W_MARGIN = 20.0; const double DAWN_H_MARGIN = 20.0; const double DAWN_WIDTH = A4_WIDTH - 2.0 * DAWN_W_MARGIN ; const double DAWN_HEIGHT = A4_HEIGHT - 2.0 * DAWN_H_MARGIN ; //----- default shift of bounding box const double DEFAULT_H_SHIFT = 0.0 ; const double DEFAULT_V_SHIFT = 0.0 ; //----- size of line buffer const int BUFSIZE = 1024 ; //----- output functions void output( const char* string , ostream* out_p = &cout ) { (*out_p) << string << flush ; } void output( char* string , ostream* out_p = &cout ) { (*out_p) << string << flush ; } void output( int val , ostream* out_p = &cout ) { (*out_p) << val << flush ; } void output( double val , ostream* out_p = &cout ) { (*out_p) << val << flush ; } void output( double val1 , double val2 , char* string , ostream* out_p = &cout ) { (*out_p) << val1 << " " << val2 << " " << string << flush ; } void output_line( char* string , ostream* out_p = &cout ) { (*out_p) << string << endl; } //----- macro --> value int analyse_macro( char* string, double* val_p ) { //----- local char buf[64]; double ratio ; int status = 1 ; // initialize to NORMAL int status_tmp = 0 ; //----- a4w if ( !strncmp( string, "a4w", 3 ) ) { if( strlen(string) == 3 ) { ratio = 1.0 ; } else { ratio = 0.0 ; // initialized to dummy value strcpy( buf, &(string[3]) ) ; status_tmp = sscanf( buf, "%lf", &ratio ); if( status_tmp == EOF || ratio <= 0.0 ) { ratio = 1.0 ; } } *val_p = ratio * A4_WIDTH ; } //----- a4 height else if ( !strncmp( string, "a4h", 3 ) ) { if( strlen(string) == 3 ) { ratio = 1.0 ; } else { ratio = 0.0 ; // initialized to dummy value strcpy( buf, &(string[3]) ) ; status_tmp = sscanf( buf, "%lf", &ratio ); if( status_tmp == EOF || ratio <= 0.0 ) { ratio = 1.0 ; } } *val_p = ratio * A4_HEIGHT ; } //----- dawn width else if ( !strcmp(string, "dw") ) { *val_p = DAWN_WIDTH ; } //----- dawn height else if ( !strcmp(string, "dh") ) { *val_p = DAWN_HEIGHT ; } else { status = 0 ; // undefined macro } //----- return value return status ; }// analyse_macro() void usage () { cerr << endl; cerr << "***** DAWN EPS CLIPPER (ver " << VERSION << ") *****" << endl; cerr << " Jan 27, 1997 " << endl; cerr << " Fukui University, S.TANAKA" << endl; cerr << endl; cerr << "USAGE: dawn_epsclipper input_eps_file width_mm height_mm [output_eps_file]" << endl; cerr << endl; cerr << " This tool clips EPS figure generated by DAWN" << endl; cerr << " with a \"width_mm x height_mm\" rectangle." << endl; cerr << " By default, center of the rectangle is the center of the figure." << endl; cerr << " You can shift the center after invoking this tool. " << endl; cerr << " If the last argument is not given, the result is output to stdout. " << endl; cerr << endl; cerr << "MACROS:" << endl; cerr << " a4w[val] = 210 x val (= A4_WIDTH (mm) x val)" << endl; cerr << " a4h[val] = 297 x val (= A4_HEIGHT (mm) x val)" << endl; cerr << " dw = 170 (= width of DAWN figure (mm))" << endl; cerr << " dh = 257 (= width of DAWN figure (mm))" << endl; cerr << endl; cerr << "EXAMPLE:" << endl; cerr << " If you want to clip your figure of g4.eps with " << endl; cerr << " half-A4-width x half-A4-height rectangle " << endl; cerr << " and output the result into a file g4_clipped.eps, " << endl; cerr << " do as follows:" << endl; cerr << " \% dawn_epsclipper g4.eps a4w0.5 a4h0.5 g4_clipped.eps" << endl; cerr << endl; } //----- main int main( int argc, char* argv[] ) { //----- variables double clip_left_pt = 0.0 , clip_bottom_pt = 0.0 ; double clip_right_pt = 0.0 , clip_top_pt = 0.0 ; double clip_width_pt = 0.0 , clip_height_pt = 0.0 ; double h_shift_pt = 0.0 , v_shift_pt = 0.0 ; double clip_width_mm = 0.0 , clip_height_mm = 0.0 ; double h_shift_mm = 0.0 , v_shift_mm = 0.0 ; double value_tmp ; ifstream fin ; char buf[BUFSIZE] ; char s_2[BUFSIZE] ; char word[2][BUFSIZE] ; ostream* out_p = NULL ; ofstream fout ; //----- define output stream if( argc == 5 ) { //----- stream to given file in argv[4] fout.open( argv[4] ); if( !fout ) { cerr << "Error: Cannot open file " << argv[4] << "." << endl; exit(1) ; } out_p = &fout ; } else if ( argc == 4 ) { //----- stream to stdout out_p = &cout ; } else { usage(); exit(1) ; } //----- check validity of input file fin.open( argv[1] ); if( !fin ) { cerr << "Error: Cannot open file " << argv[1] << "." << endl; exit(1) ; } else { fin.getline( buf, BUFSIZE ); if( buf[0] != '%' || buf[1] != '!' ) { cerr << "Error: Given file does not have a header comment." << endl; exit(1) ; } fin.close(); } //----- read input width if( analyse_macro( argv[2], &value_tmp ) ) { clip_width_mm = value_tmp ; } else if( sscanf( argv[2], "%lg", &clip_width_mm ) == EOF ) { cerr << "ERROR in arg[2] " << endl; exit(1) ; } else { if( clip_width_mm > A4_WIDTH ) { cerr << "WARNING: Given clipping width exceeds A4 width." << endl; cerr << " (Clipping width is reset to A4 width.) " << endl; clip_width_mm = A4_WIDTH ; } if( clip_width_mm <= 0.0 ) { cerr << "ERROR: Given clipping width is non-positive," << endl; cerr << " or undefined macro is used." << endl; exit(1); } } clip_width_pt = clip_width_mm * ptOverMm ; //----- read height if( analyse_macro( argv[3], &value_tmp ) ) { clip_height_mm = value_tmp ; } else if( sscanf( argv[3], "%lg", &clip_height_mm ) == EOF ) { cerr << "ERROR in arg[3] " << endl; exit(1) ; } else { if( clip_height_mm > A4_HEIGHT ) { cerr << "WARNING: Given clipping height exceeds A4 height." << endl; cerr << " (Clipping height is reset to A4 height.) " << endl; clip_height_mm = A4_HEIGHT ; } if( clip_height_mm <= 0.0 ) { cerr << "ERROR: Given clipping height is non-positive," << endl; cerr << " or undefined macro is used." << endl; exit(1); } } clip_height_pt = clip_height_mm * ptOverMm ; //----- set shift of bounding box (mm) h_shift_mm = DEFAULT_H_SHIFT ; // initialize to default value v_shift_mm = DEFAULT_V_SHIFT ; // initialize to default value cerr << "Input shift of bounding box in units of mm " ; cerr << "( default is " << h_shift_mm << " " ; cerr << v_shift_mm << "): " << flush; gets(s_2); // accept input from keyboard if(strlen(s_2) != 0 ) { //----- performed if non-null string is input //----- local istrstream str_in(s_2) ; //----- analyze input string if( !(str_in >> word[0] >> word[1]) ) { //----- if error, keep default values h_shift_mm = DEFAULT_H_SHIFT ; // set default v_shift_mm = DEFAULT_V_SHIFT ; // set default } else { //----- set h_shift_mm if( analyse_macro( word[0], &value_tmp ) ) { //----- set value analyzed from macro h_shift_mm = value_tmp ; } else if( sscanf( word[0], "%lg", &value_tmp ) != EOF ) { //----- Since input string is a value (not a macro), set it. h_shift_mm = value_tmp ; } else { //----- sscanf failed: set default values cerr << "WARNING: Cannot accept h_shift (use default value and continue)\n"; h_shift_mm = DEFAULT_H_SHIFT ; // set default } //----- v_shift_mm if( analyse_macro( word[1], &value_tmp ) ) { //----- set value analyzed from macro v_shift_mm = value_tmp ; } else if( sscanf( word[1], "%lg", &value_tmp ) != EOF ) { //----- Since input string is a value (not a macro), set it. v_shift_mm = value_tmp ; } else { //----- sscanf failed: set default values cerr << "WARNING: Cannot accept v_shift (use default value and continue)\n"; v_shift_mm = DEFAULT_V_SHIFT ; // set default } } } else { // do nothing and keep dafault values } //----- set shift of bounding box (pt) h_shift_pt = h_shift_mm * ptOverMm ; v_shift_pt = v_shift_mm * ptOverMm ; //----- calc clipping area clip_left_pt = 0.5 * ( A4_WIDTH_pt - clip_width_pt ) + h_shift_pt ; clip_bottom_pt = 0.5 * ( A4_HEIGHT_pt - clip_height_pt ) + v_shift_pt ; clip_right_pt = clip_left_pt + clip_width_pt ; clip_top_pt = clip_bottom_pt + clip_height_pt ; //----- read input file and modify BoundingBox comment fin.open( argv[1] ); if( !fin ) { cerr << "Error: Cannot open file " << argv[1] << "." << endl; exit(1) ; } if ( argc == 5 ) { cerr << "\nMaking a new EPS file \"" << argv[4] << "\" ...\n" << endl; } else if ( argc == 4 ) { cerr << "\nOutputting result to \"stdout\" ...\n" << endl; } while( fin.getline( buf, BUFSIZE ) ) { if( !strncmp( buf, EPS_BOUNDING_BOX , LENGTH_EPS_BOUNDING_BOX ) ) { //----- output new BoundingBox comment output ( EPS_BOUNDING_BOX , out_p ) ; output(" " , out_p ) ; output ( clip_left_pt , out_p ) ; output(" " , out_p ) ; output ( clip_bottom_pt , out_p ) ; output(" " , out_p ) ; output ( clip_right_pt , out_p ) ; output(" " , out_p ) ; output ( clip_top_pt , out_p ) ; output("\n", out_p ) ; //----- output original BoundingBox comment output( "%*** Original Bounding Box is: " , out_p ) ; output_line ( buf , out_p ) ; //----- clip output("newpath\n" , out_p ) ; output(clip_left_pt , clip_bottom_pt , "moveto\n", out_p ); output(clip_right_pt , clip_bottom_pt , "lineto\n", out_p ); output(clip_right_pt , clip_top_pt , "lineto\n", out_p ); output(clip_left_pt , clip_top_pt , "lineto\n", out_p ); output("closepath clip\n" , out_p ) ; } else { //----- output a line without modification output_line( buf , out_p ) ; } } fin.close(); //----- ending message output ( "DONE:\t", &cerr ) ; output ( EPS_BOUNDING_BOX , &cerr ) ; output(" " , &cerr ) ; output ( clip_left_pt , &cerr ) ; output(" " , &cerr ) ; output ( clip_bottom_pt , &cerr ) ; output(" " , &cerr ) ; output ( clip_right_pt , &cerr ) ; output(" " , &cerr ) ; output ( clip_top_pt , &cerr ) ; output("\n\n", &cerr ) ; } // main()