Skip to content
Snippets Groups Projects
dawn_epsclipper.cc 10.8 KiB
Newer Older
Whitney Armstrong's avatar
Whitney Armstrong committed
#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()