Logo Search packages:      
Sourcecode: ncview version File versions  Download package

do_print.c

/*
 * Ncview by David W. Pierce.  A visual netCDF file viewer.
 * Copyright (C) 1993 through 2009 David W. Pierce
 *
 * This program  is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as 
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License, version 3, for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * David W. Pierce
 * 6259 Caminito Carrean
 * San Diego, CA   92122
 * pierce@cirrus.ucsd.edu
 */

/*     define DEBUG */

#include "ncview.includes.h"
#include "ncview.defines.h"
#include "ncview.protos.h"

#define PAGE_WIDTH_INCHES     8.5
#define PAGE_HEIGHT_INCHES    11.5
#define PAGE_X_MARGIN         1.5   /* Inches */
#define PAGE_UPPER_Y_MARGIN   2.0   /* Inches */
#define PAGE_LOWER_Y_MARGIN   4.0   /* Inches */

#define FONT_SIZE       11
#define HEADER_FONT_SIZE      16
#define FONT_NAME       "Helvetica"
#define LEADING               3

#define DEFAULT_DEVICE        DEVICE_PRINTER
#define     INCLUDE_OUTLINE         TRUE
#define     INCLUDE_TITLE           TRUE
#define     INCLUDE_AXIS_LABELS     TRUE
#define     INCLUDE_EXTRA_INFO      TRUE
#define     INCLUDE_ID        TRUE
#define TEST_ONLY       FALSE

#define     ID_FONT_SIZE_SCALE      0.7   /* How much smaller ID font size is than regular */

extern View       *view;
extern Options    options;

static PrintOptions printopts;

static void print_header( FILE *out_file, float scale, size_t x, size_t y, size_t top_of_image );
static void calc_scale( float *scale, size_t x, size_t y );
static void set_font( FILE *outf, char *name, int size );
static void do_outline( FILE *f, size_t x, size_t y );
static void print_other_info( FILE *out_file, float output_scale, size_t x_size, size_t y_size, 
                  size_t center_x, size_t center_y, size_t top_of_image, size_t bot_of_image );

/********************************************************************/

      void
print_init( void )
{
      printopts.page_width          = PAGE_WIDTH_INCHES; 
      printopts.page_height         = PAGE_HEIGHT_INCHES;
      printopts.page_x_margin       = PAGE_X_MARGIN;
      printopts.page_upper_y_margin       = PAGE_UPPER_Y_MARGIN;
      printopts.page_lower_y_margin       = PAGE_LOWER_Y_MARGIN;
      printopts.ppi                 = 72.0;

      printopts.leading             = LEADING;
      printopts.font_size           = FONT_SIZE;
      printopts.header_font_size    = HEADER_FONT_SIZE;

      printopts.output_device       = DEFAULT_DEVICE;
      printopts.include_outline     = INCLUDE_OUTLINE;
      printopts.include_id          = INCLUDE_ID;
      printopts.include_title       = INCLUDE_TITLE;
      printopts.include_axis_labels = INCLUDE_AXIS_LABELS;
      printopts.include_extra_info  = INCLUDE_EXTRA_INFO;

      printopts.test_only           = TEST_ONLY;

      strcpy( printopts.font_name, FONT_NAME );

      printer_options_init(); /* this initializes the X-windows interface
                           part of the pinter options panel */
}

/*************************************************************************/

      void
do_print( void )
{
      long  i, j;
      size_t      x_size, y_size, scaled_x_size, scaled_y_size, top_of_image, bot_of_image, 
            center_x, center_y, left_of_image, right_of_image;
      char  outfname[1024], tstr[1500];
      int     outfid;
      FILE  *outf;
      float output_scale;
      int   r, g, b, n_print;
      ncv_pixel pix;

#ifdef DEBUG
      fprintf( stderr, "entering do_print()\n" );
#endif
      x_size = *(view->variable->size + view->x_axis_id);
      y_size = *(view->variable->size + view->y_axis_id);
      view_get_scaled_size( options.blowup, x_size, y_size, &scaled_x_size, &scaled_y_size );

      snprintf( printopts.out_file_name, 1024, "ncview.%s.ps", view->variable->name ); 
      if( printer_options( &printopts ) == MESSAGE_CANCEL )
            return;

      if( printopts.output_device == DEVICE_PRINTER ) {
          strcpy( printopts.out_file_name, "/tmp/ncview.XXXXXX" );
          outfid = mkstemp( printopts.out_file_name );
          if (outfid == -1) {
            snprintf( tstr, 1499, "Error opening temporary file for output!\n" );
            in_error( tstr );
            return;
          }
          if( (outf = fopen(printopts.out_file_name, "a" )) == NULL ) {
            snprintf( tstr, 1499, "Error opening file %s for output!\n",
                   printopts.out_file_name );
            in_error( tstr );
            return;
          }
          close(outfid);
      }
      else {
          if( warn_if_file_exits( printopts.out_file_name ) == MESSAGE_CANCEL )
            return;
          
          if( (outf = fopen(printopts.out_file_name, "w" )) == NULL ) {
            snprintf( tstr, 1499, "Error opening file %s for output!\n",
                   outfname );
            in_error( tstr );
            return;
          }
      }
      
      in_set_cursor_busy();
      calc_scale( &output_scale, scaled_x_size, scaled_y_size );

      /* These are all in absolute points in the default coordinate system */
      top_of_image   = (size_t)(printopts.page_height*printopts.ppi -
                        printopts.page_upper_y_margin*printopts.ppi);
      bot_of_image   = top_of_image - (long)((float)scaled_y_size*output_scale);
      left_of_image  = (size_t)(printopts.page_x_margin*printopts.ppi);
      right_of_image = left_of_image + (long)((float)scaled_x_size*output_scale);
      center_y       = (top_of_image + bot_of_image)/2;
      center_x       = (size_t)(((float)left_of_image + (float)right_of_image)/2.0);

      print_header( outf, output_scale, scaled_x_size, scaled_y_size, top_of_image );

      /***** dump out the color image *****/
      if( ! printopts.test_only ) {
            view_draw( FALSE, FALSE ); /* Don't allow saveframes -- force reload of image data */
            n_print = 0;
            for( j=0; j<scaled_y_size; j++ ) {
                  for( i=0; i<scaled_x_size; i++ ) {
                        pix = *(view->pixels + j*scaled_x_size + i);
                        pix_to_rgb( pix, &r, &g, &b );
                        fprintf( outf, "%02x%02x%02x", (r>>8), (g>>8), (b>>8)); 
                        n_print += 6;
                        if( n_print > 70 ) {
                              fprintf( outf, "\n" );
                              n_print = 0;
                              }
                        }
                  }
            fprintf( outf, "\n\n" );
            }
      
      /* Outline the color contour with lines */
      if( printopts.include_outline ) 
            do_outline( outf, scaled_x_size, scaled_y_size );

      fprintf( outf, "\n\ngrestore\n" );

      print_other_info( outf, output_scale, scaled_x_size, scaled_y_size, center_x, center_y, 
                  top_of_image, bot_of_image );

#ifdef DEBUG
      fprintf( stderr, "exiting do_print()\n" );
#endif
}

/*************************************************************************/

      static void
print_other_info( FILE *outf, float output_scale, size_t x_size, size_t y_size, 
                  size_t center_x, size_t center_y, 
                  size_t top_of_image, size_t bot_of_image )
{
      char  *units, *x_dim_name, *x_dim_longname,
            *y_dim_name, *y_dim_longname, *x_units, *y_units,
            tstr[1500], tstr2[1000], *main_long_name, *main_units,
            *dim_name, *dim_longname;
      FDBlist     *fdb;
      NCDim *d;
      int   i, type, has_bounds;
      size_t      *actual_place;
      time_t      sec_since_1970;
      double      temp_double, bound_min, bound_max;
      FILE  *f_dummy;

#ifdef DEBUG
      fprintf( stderr, "print_other_info: entering\n" );
#endif
      x_dim_name     = (*(view->variable->dim + view->x_axis_id))->name;
      x_dim_longname = fi_dim_longname( view->variable->first_file->id, x_dim_name );
      x_units        = fi_dim_units( view->variable->first_file->id, x_dim_name );

      y_dim_name     = (*(view->variable->dim + view->y_axis_id))->name;
      y_dim_longname = fi_dim_longname( view->variable->first_file->id, y_dim_name );
      y_units        = fi_dim_units( view->variable->first_file->id, y_dim_name );

      main_long_name = fi_long_var_name( view->variable->first_file->id, 
                  view->variable->name );
      if( main_long_name == NULL )
            main_long_name = view->variable->name;
      main_units     = fi_var_units( view->variable->first_file->id, view->variable->name );

      /***** Main variable name and units ******/
      if( printopts.include_title ) {
            snprintf( tstr, 1499, "%s", main_long_name );
            if( main_units != NULL ) {
                  strcat( tstr, " (" );
                  strcat( tstr, main_units );
                  strcat( tstr, ")" );
                  }

            /* move to the center, then half the string's width */
            set_font( outf, printopts.font_name, printopts.header_font_size );
            fprintf( outf, "%ld %ld moveto\n", 
                        center_x,
                        top_of_image+printopts.font_size );
            fprintf( outf, "(%s) stringwidth pop -0.5 mul 0 rmoveto\n", tstr );
            fprintf( outf, "(%s) show\n", tstr );
            }

      /***** X axis title *****/
      if( printopts.include_axis_labels ) {
            set_font( outf, printopts.font_name, printopts.font_size );
            strcpy( tstr, x_dim_longname );
            if( x_units != NULL ) {
                  strcat( tstr, " (" );
                  strcat( tstr, x_units );
                  strcat( tstr, ")" );
                  }
            fprintf( outf, "%ld %ld moveto\n", 
                  center_x, bot_of_image-(long)(1.5*(float)printopts.font_size) );
            fprintf( outf, "(%s) stringwidth pop -0.5 mul 0 rmoveto\n", tstr );
            fprintf( outf, "(%s) show\n", tstr );

            /***** Y axis title *****/
            set_font( outf, printopts.font_name, printopts.font_size );
            strcpy( tstr, y_dim_longname );
            if( y_units != NULL ) {
                  strcat( tstr, " (" );
                  strcat( tstr, y_units );
                  strcat( tstr, ")" );
                  }
            fprintf( outf, "%ld %ld moveto\n", 
                  center_x - (long)((float)x_size*output_scale/2.0),
                  center_y );
            fprintf( outf, "gsave 90 rotate 0 %d rmoveto\n", 
                        (int)((float)printopts.font_size*output_scale) );
            fprintf( outf, "(%s) stringwidth pop -0.5 mul 0 rmoveto\n", tstr );
            fprintf( outf, "(%s) show grestore\n", tstr );
            }

      /***************** Other information *******************/
      if( printopts.include_extra_info ) {
            set_font( outf, printopts.font_name, printopts.font_size );
            fprintf( outf, "%ld %ld moveto\n", (long)(printopts.page_x_margin*printopts.ppi),
                  bot_of_image - 4*printopts.font_size );

            /**** File title ***/
            if( fi_title( view->variable->first_file->id ) != NULL ) {
                  fprintf( outf, "gsave (%s) show grestore\n", 
                        fi_title( view->variable->first_file->id ) );
                  fprintf( outf, "0 %d rmoveto\n", 
                        -(printopts.leading+printopts.font_size) );
                  }

            /*** Range of data ***/
            snprintf( tstr, 1499, "Range of %s: %g to %g %s", main_long_name, 
                  view->variable->user_min, view->variable->user_max, main_units );
            fprintf( outf, "gsave (%s) show grestore\n", tstr );
            fprintf( outf, "0 %d rmoveto\n", -(printopts.leading+printopts.font_size) );

            /*** Range of X axis ***/
            d = *(view->variable->dim + view->x_axis_id);
            if( x_units == NULL )
                  snprintf( tstr, 1499, "Range of %s: %g to %g", 
                        x_dim_longname, d->min, d->max);
            else
                  snprintf( tstr, 1499, "Range of %s: %g to %g %s", 
                        x_dim_longname, d->min, d->max, x_units );
            fprintf( outf, "gsave (%s) show grestore\n", tstr );
            fprintf( outf, "0 %d rmoveto\n", -(printopts.leading+printopts.font_size) );

            /*** Range of Y axis ***/
            d = *(view->variable->dim + view->y_axis_id);
            if( options.invert_physical ) 
                  snprintf( tstr, 1499, "Range of %s: %g to %g", 
                        y_dim_longname, d->max, d->min );
            else
                  snprintf( tstr, 1499, "Range of %s: %g to %g", 
                        y_dim_longname, d->min, d->max );
            if( y_units != NULL ) {
                  strcat( tstr, " " );
                  strcat( tstr, y_units );
                  }
            fprintf( outf, "gsave (%s) show grestore\n", tstr );
            fprintf( outf, "0 %d rmoveto\n", -(printopts.leading+printopts.font_size) );

            /*** Values of other dimensions ***/
            for(i=0; i<view->variable->n_dims; i++)
                  if( (i != view->x_axis_id) && 
                      (i != view->y_axis_id) &&
                      (*(view->variable->dim+i) != NULL)) {
                        dim_name     = (*(view->variable->dim + i))->name;
                        dim_longname = fi_dim_longname( view->variable->first_file->id, dim_name );
                        units        = fi_dim_units( view->variable->first_file->id, dim_name );
                        type         = fi_dim_value( view->variable, i, *(view->var_place+i),
                                          &temp_double, tstr2, &has_bounds, &bound_min, &bound_max, view->var_place );
                        if( type == NC_DOUBLE )
                              snprintf( tstr, 1499, "Current %s: %lg", dim_longname, temp_double );
                        else
                              snprintf( tstr, 1499, "Current %s: %s", dim_longname,
                                    tstr2 );
                        if( units != NULL ) {
                              strcat( tstr, " " );
                              strcat( tstr, units );
                              }
                        fprintf( outf, "gsave (%s) show grestore\n", tstr );
                        fprintf( outf, "0 %d rmoveto\n", -(printopts.leading+printopts.font_size) );
                        }
                  
            /*** Name of file ***/
            tstr[0] = '\0';
            actual_place = (size_t *)malloc( sizeof(size_t)*20 );
            virt_to_actual_place( view->variable, view->var_place, actual_place, &fdb );
            if( (fi_recdim_id( view->variable->first_file->id ) != view->x_axis_id ) &&
                (fi_recdim_id( view->variable->first_file->id ) != view->y_axis_id)) 
                  snprintf( tstr, 1499, "Frame %ld in ", 
                        *(actual_place + view->scan_axis_id)+1 );
            strcat( tstr, "File " );
            strcat( tstr, fdb->filename );
            fprintf( outf, "gsave (%s) show grestore\n", tstr );
            fprintf( outf, "0 %d rmoveto\n", -(printopts.leading+printopts.font_size) );
            }

      if( printopts.include_id ) {
            sec_since_1970 = time(NULL);
            snprintf( tstr, 1499, "%s %s", getlogin(), ctime(&sec_since_1970) );
            /* Make the id font a bit smaller */
            set_font( outf, printopts.font_name, 
                        (int)((float)printopts.font_size*ID_FONT_SIZE_SCALE) );
            fprintf( outf, "gsave %ld %ld translate 0 0 moveto\n", 
                  center_x + (long)((float)x_size*output_scale/2.0) 
                                    + printopts.font_size + printopts.leading,
                  bot_of_image );
            fprintf( outf, "90 rotate (%s) show grestore\n", tstr );
            }

      /****** All done! *****/
      fprintf( outf, "\n\nshowpage\n" );
      fclose( outf );
      if( printopts.output_device == DEVICE_PRINTER ) {
            /* Before executing the command, ensure that the file name exists ... helps
             * to prevent problems if a strange file name is specified, such as "out.ps ; rm -r ."
             */
            if( (f_dummy = fopen( printopts.out_file_name, "r" )) == NULL ) {
                  fprintf( stderr, "Error, could not open file \"%s\" for reading, which is a prerequisite to printing it\n",
                        printopts.out_file_name );
                  exit( -1 );
                  }
            fclose( f_dummy );
            snprintf( tstr, 1499, "lpr \"%s\"\n", printopts.out_file_name );
            system( tstr );
            unlink( printopts.out_file_name );
            }

      fprintf( stdout, "" );
      fflush( stdout );
      in_set_cursor_normal();
#ifdef DEBUG
      fprintf( stderr, "print_other_info: exiting\n" );
#endif
}

      static void
set_font( FILE *outf, char *name, int size )
{
      fprintf( outf, "/%s findfont\n", name );
      fprintf( outf, "%d scalefont setfont\n", size );
}

      static void
calc_scale( float *scale, size_t x, size_t y )
{
      size_t      page_width, page_height;
      float scale_x, scale_y;

      page_width = (printopts.page_width-2.0*printopts.page_x_margin)*printopts.ppi;
      page_height =   (printopts.page_height -
                     (printopts.page_upper_y_margin + printopts.page_lower_y_margin)
                  )*printopts.ppi;

      scale_x = page_width / (float)x;
      scale_y = page_height / (float)y;

      *scale = (scale_x < scale_y) ? scale_x : scale_y;
}

      static void
do_outline( FILE *f, size_t x, size_t y )
{
      fprintf( f, "newpath\n" );
      fprintf( f, "0 0 moveto\n" );
      fprintf( f, "0 %ld lineto\n", -y );
      fprintf( f, "%ld %ld lineto\n", x, -y );
      fprintf( f, "%ld 0 lineto\n", x );
      fprintf( f, "0 0 lineto\n" );
      fprintf( f, "closepath stroke\n" );
}

      static void
print_header( FILE *f, float scale, size_t x, size_t y, size_t top_of_image )
{
      fprintf( f, "%%!\n" );
      fprintf( f, "/picstr %ld string def\n", x*3 );
      fprintf( f, "gsave\n" );

      /* This sets the position of the output image on the page */
      fprintf( f, "%ld %ld translate\n", 
                  (long)(printopts.page_x_margin*printopts.ppi), top_of_image );

      /* This sets the size of the image */
      fprintf( f, "%f %f scale\n", scale, scale );

      if( printopts.test_only ) {
            fprintf( f, "newpath\n" );
            fprintf( f, "0 0 moveto\n" );
            fprintf( f, "0 %ld lineto\n", -y );
            fprintf( f, "%ld %ld lineto\n", x, -y );
            fprintf( f, "%ld 0 lineto\n", x );
            fprintf( f, "0 0 lineto\n" );
            fprintf( f, "%ld %ld lineto\n", x, -y );
            fprintf( f, "0 %ld moveto\n", -y );
            fprintf( f, "%ld 0 lineto\n", x );
            fprintf( f, "closepath stroke\n" );
            }
      else
            {
            fprintf( f, "%ld %ld 8\n", x, y );
            fprintf( f, "[1 0 0 -1 0 1]\n" );
            fprintf( f, "{currentfile picstr readhexstring pop}\n" );
            fprintf( f, "false 3\n" );
            fprintf( f, "colorimage\n\n" );
            }
}


Generated by  Doxygen 1.6.0   Back to index