-
Whitney Armstrong authored5dc2d851
dawn_epsclipper.cc 10.79 KiB
#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()