2006-12-10 05:33:38 +08:00
/* GIMP - The GNU Image Manipulation Program
1997-11-25 06:05:25 +08:00
* Copyright ( C ) 1995 Spencer Kimball and Peter Mattis
* PostScript file plugin
* PostScript writing and GhostScript interfacing code
1999-01-04 06:41:12 +08:00
* Copyright ( C ) 1997 - 98 Peter Kirchgessner
* ( email : peter @ kirchgessner . net , WWW : http : //www.kirchgessner.net)
1997-11-25 06:05:25 +08:00
*
* Added controls for TextAlphaBits and GraphicsAlphaBits
* George White < aa056 @ chebucto . ns . ca >
*
2000-01-23 06:26:20 +08:00
* Added Ascii85 encoding
* Austin Donnelly < austin @ gimp . org >
*
1997-11-25 06:05:25 +08:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* 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 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
1998-04-13 13:44:11 +08:00
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
1997-11-25 06:05:25 +08:00
*
*/
/* Event history:
* V 0.90 , PK , 28 - Mar - 97 : Creation .
* V 0.91 , PK , 03 - Apr - 97 : Clip everything outside BoundingBox .
* 24 - Apr - 97 : Multi page read support .
* V 1.00 , PK , 30 - Apr - 97 : PDF support .
* V 1.01 , PK , 05 - Oct - 97 : Parse rc - file .
* V 1.02 , GW , 09 - Oct - 97 : Antialiasing support .
* PK , 11 - Oct - 97 : No progress bars when running non - interactive .
* New procedure file_ps_load_setargs to set
* load - arguments non - interactively .
* If GS_OPTIONS are not set , use at least " -dSAFER "
1997-12-26 15:08:20 +08:00
* V 1.03 , nn , 20 - Dec - 97 : Initialize some variables
* V 1.04 , PK , 20 - Dec - 97 : Add Encapsulated PostScript output and preview
1999-01-04 06:41:12 +08:00
* V 1.05 , PK , 21 - Sep - 98 : Write b / w - images ( indexed ) using image - operator
* V 1.06 , PK , 22 - Dec - 98 : Fix problem with writing color PS files .
* Ghostview may hang when displaying the files .
1999-09-15 04:54:02 +08:00
* V 1.07 , PK , 14 - Sep - 99 : Add resolution to image
2000-01-23 06:26:20 +08:00
* V 1.08 , PK , 16 - Jan - 2000 : Add PostScript - Level 2 by Austin Donnelly
2000-03-11 01:27:25 +08:00
* V 1.09 , PK , 15 - Feb - 2000 : Force showpage on EPS - files
* Add " RunLength " compression
* Fix problem with " Level 2 " toggle
2000-04-05 18:26:08 +08:00
* V 1.10 , PK , 15 - Mar - 2000 : For load EPSF , allow negative Bounding Box Values
2000-03-26 06:19:17 +08:00
* Save PS : dont start lines of image data with % %
* to prevent problems with stupid PostScript
* analyzer programs ( Stanislav Brabec )
2000-04-05 18:26:08 +08:00
* Add BeginData / EndData comments
* Save PS : Set default rotation to 0
2000-08-21 07:26:11 +08:00
* V 1.11 , PK , 20 - Aug - 2000 : Fix problem with BoundingBox recognition
* for Mac files .
* Fix problem with loop when reading not all
* images of a multi page file .
2000-10-07 02:16:58 +08:00
* PK , 31 - Aug - 2000 : Load PS : Add checks for space in filename .
2001-06-21 17:25:06 +08:00
* V 1.12 PK , 19 - Jun - 2001 : Fix problem with command line switch - -
* ( reported by Ferenc Wagner )
2002-04-11 18:58:19 +08:00
* V 1.13 PK , 07 - Apr - 2002 : Fix problem with DOS binary EPS files
2002-05-15 04:04:29 +08:00
* V 1.14 PK , 14 - May - 2002 : Workaround EPS files of Adb . Ill . 8.0
2002-10-08 18:53:10 +08:00
* V 1.15 PK , 04 - Oct - 2002 : Be more accurate with using BoundingBox
2004-01-26 07:46:24 +08:00
* V 1.16 PK , 22 - Jan - 2004 : Don ' t use popen ( ) , use g_spawn_async_with_pipes ( )
* or g_spawn_sync ( ) .
2004-09-19 18:54:48 +08:00
* V 1.17 PK , 19 - Sep - 2004 : Fix problem with interpretation of bounding box
1997-11-25 06:05:25 +08:00
*/
2004-09-19 18:54:48 +08:00
# define VERSIO 1.17
static char dversio [ ] = " v1.17 19-Sep-2004 " ;
1997-11-25 06:05:25 +08:00
1999-05-30 00:35:47 +08:00
# include "config.h"
2000-01-08 23:23:28 +08:00
2003-06-13 22:37:00 +08:00
# include <errno.h>
1997-11-25 06:05:25 +08:00
# include <string.h>
# include <time.h>
2000-01-08 23:23:28 +08:00
2004-01-26 07:46:24 +08:00
# include <sys/types.h>
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
2005-03-04 23:12:29 +08:00
# include <glib/gstdio.h>
2000-01-08 23:23:28 +08:00
# include <libgimp/gimp.h>
# include <libgimp/gimpui.h>
1999-05-30 00:35:47 +08:00
# include "libgimp/stdplugins-intl.h"
1999-10-05 03:26:07 +08:00
# ifdef G_OS_WIN32
2004-01-26 07:46:24 +08:00
/* On Win32 we don't use pipes. Use a real output file for ghostscript */
1999-06-21 08:23:55 +08:00
# define USE_REAL_OUTPUTFILE
1998-07-14 14:15:10 +08:00
# endif
2000-01-23 06:26:20 +08:00
2004-01-26 07:46:24 +08:00
# ifdef USE_REAL_OUTPUTFILE
# ifdef G_OS_WIN32
# include <process.h> /* For _getpid() */
# endif
# else
# ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
# endif
# endif
2005-08-15 18:30:39 +08:00
# define LOAD_PS_PROC "file-ps-load"
# define LOAD_EPS_PROC "file-eps-load"
# define LOAD_PDF_PROC "file-pdf-load"
# define LOAD_PS_SETARGS_PROC "file-ps-load-setargs"
# define LOAD_PS_THUMB_PROC "file-ps-load-thumb"
# define SAVE_PS_PROC "file-ps-save"
# define SAVE_EPS_PROC "file-eps-save"
# define PLUG_IN_BINARY "postscript"
1997-11-25 06:05:25 +08:00
# define STR_LENGTH 64
2003-03-22 09:12:48 +08:00
# ifndef G_OS_WIN32
# define DEFAULT_GS_PROG "gs"
# else
/* We want the console ghostscript application. It should be in the PATH */
# define DEFAULT_GS_PROG "gswin32c"
# endif
1997-11-25 06:05:25 +08:00
/* Load info */
typedef struct
{
2000-01-26 01:46:56 +08:00
guint resolution ; /* resolution (dpi) at which to run ghostscript */
guint width , height ; /* desired size (ghostscript may ignore this) */
gint use_bbox ; /* 0: use width/height, 1: try to use BoundingBox */
gchar pages [ STR_LENGTH ] ; /* Pages to load (eg.: 1,3,5-7) */
gint pnm_type ; /* 4: pbm, 5: pgm, 6: ppm, 7: automatic */
gint textalpha ; /* antialiasing: 1,2, or 4 TextAlphaBits */
gint graphicsalpha ; /* antialiasing: 1,2, or 4 GraphicsAlphaBits */
1997-11-25 06:05:25 +08:00
} PSLoadVals ;
static PSLoadVals plvals =
{
2004-11-19 05:36:10 +08:00
100 , /* 100 dpi */
826 , 1170 , /* default width/height (A4) */
1 , /* try to use BoundingBox */
" 1 " , /* pages to load */
6 , /* use ppm (colour) */
1 , /* dont use text antialiasing */
1 /* dont use graphics antialiasing */
1997-11-25 06:05:25 +08:00
} ;
/* Save info */
typedef struct
{
gdouble width , height ; /* Size of image */
gdouble x_offset , y_offset ; /* Offset to image on page */
2000-01-26 01:46:56 +08:00
gint unit_mm ; /* Unit of measure (0: inch, 1: mm) */
gint keep_ratio ; /* Keep aspect ratio */
gint rotate ; /* Rotation (0, 90, 180, 270) */
gint level ; /* PostScript Level */
gint eps ; /* Encapsulated PostScript flag */
gint preview ; /* Preview Flag */
gint preview_size ; /* Preview size */
1997-11-25 06:05:25 +08:00
} PSSaveVals ;
static PSSaveVals psvals =
{
287.0 , 200.0 , /* Image size (A4) */
5.0 , 5.0 , /* Offset */
1 , /* Unit is mm */
1 , /* Keep edge ratio */
2000-04-05 18:26:08 +08:00
0 , /* Rotate */
2000-01-23 06:26:20 +08:00
2 , /* PostScript Level */
1997-12-26 15:08:20 +08:00
0 , /* Encapsulated PostScript flag */
0 , /* Preview flag */
256 /* Preview size */
1997-11-25 06:05:25 +08:00
} ;
/* Declare some local functions.
*/
2003-11-27 20:28:46 +08:00
static void query ( void ) ;
static void run ( const gchar * name ,
gint nparams ,
const GimpParam * param ,
gint * nreturn_vals ,
GimpParam * * return_vals ) ;
static gint32 load_image ( const gchar * filename ) ;
static gint save_image ( const gchar * filename ,
gint32 image_ID ,
gint32 drawable_ID ) ;
static gint save_gray ( FILE * ofp ,
gint32 image_ID ,
gint32 drawable_ID ) ;
static gint save_bw ( FILE * ofp ,
gint32 image_ID ,
gint32 drawable_ID ) ;
static gint save_index ( FILE * ofp ,
gint32 image_ID ,
gint32 drawable_ID ) ;
static gint save_rgb ( FILE * ofp ,
gint32 image_ID ,
gint32 drawable_ID ) ;
static gint32 create_new_image ( const gchar * filename ,
2006-05-08 20:23:32 +08:00
guint pagenum ,
guint width ,
guint height ,
GimpImageBaseType type ,
gint32 * layer_ID ,
GimpDrawable * * drawable ,
GimpPixelRgn * pixel_rgn ) ;
1997-11-25 06:05:25 +08:00
1999-10-04 02:54:54 +08:00
static void check_load_vals ( void ) ;
static void check_save_vals ( void ) ;
1997-11-25 06:05:25 +08:00
2003-11-27 20:28:46 +08:00
static gint page_in_list ( gchar * list ,
guint pagenum ) ;
static gint get_bbox ( const gchar * filename ,
gint * x0 ,
gint * y0 ,
gint * x1 ,
gint * y1 ) ;
static FILE * ps_open ( const gchar * filename ,
const PSLoadVals * loadopt ,
gint * llx ,
gint * lly ,
gint * urx ,
gint * ury ,
2004-01-26 07:46:24 +08:00
gint * is_epsf ,
gint * ChildPid ) ;
2003-11-27 20:28:46 +08:00
2004-01-26 07:46:24 +08:00
static void ps_close ( FILE * ifp ,
gint ChildPid ) ;
2003-11-27 20:28:46 +08:00
2004-11-19 05:10:12 +08:00
static gboolean skip_ps ( FILE * ifp ) ;
2003-11-27 20:28:46 +08:00
static gint32 load_ps ( const gchar * filename ,
guint pagenum ,
FILE * ifp ,
gint llx ,
gint lly ,
gint urx ,
gint ury ) ;
static void save_ps_header ( FILE * ofp ,
const gchar * filename ) ;
static void save_ps_setup ( FILE * ofp ,
gint32 drawable_ID ,
gint width ,
gint height ,
gint bpp ) ;
static void save_ps_trailer ( FILE * ofp ) ;
static void save_ps_preview ( FILE * ofp ,
gint32 drawable_ID ) ;
2006-08-29 21:32:22 +08:00
static void dither_grey ( const guchar * grey ,
2003-11-27 20:28:46 +08:00
guchar * bw ,
gint npix ,
gint linecount ) ;
1997-11-25 06:05:25 +08:00
/* Dialog-handling */
1999-10-04 02:54:54 +08:00
2005-08-15 16:48:45 +08:00
static gint32 count_ps_pages ( const gchar * filename ) ;
static gboolean load_dialog ( const gchar * filename ,
gboolean loadPDF ) ;
static void load_pages_entry_callback ( GtkWidget * widget ,
gpointer data ) ;
1997-11-25 06:05:25 +08:00
typedef struct
{
2000-01-26 01:46:56 +08:00
GtkObject * adjustment [ 4 ] ;
gint level ;
1997-11-25 06:05:25 +08:00
} SaveDialogVals ;
2004-05-20 01:53:21 +08:00
static gboolean save_dialog ( void ) ;
static void save_unit_toggle_update ( GtkWidget * widget ,
gpointer data ) ;
1997-11-25 06:05:25 +08:00
2006-05-16 20:26:20 +08:00
const GimpPlugInInfo PLUG_IN_INFO =
1997-11-25 06:05:25 +08:00
{
2000-01-26 01:46:56 +08:00
NULL , /* init_proc */
NULL , /* quit_proc */
query , /* query_proc */
run , /* run_proc */
1997-11-25 06:05:25 +08:00
} ;
/* The run mode */
2001-12-19 08:13:16 +08:00
static GimpRunMode l_run_mode ;
1997-11-25 06:05:25 +08:00
2003-11-27 20:28:46 +08:00
static void compress_packbits ( int nin ,
2000-03-11 01:27:25 +08:00
unsigned char * src ,
2003-11-27 20:28:46 +08:00
int * nout ,
2000-03-11 01:27:25 +08:00
unsigned char * dst ) ;
1997-11-25 06:05:25 +08:00
2005-10-28 22:57:32 +08:00
static guint32 ascii85_buf = 0 ;
static gint ascii85_len = 0 ;
static gint ascii85_linewidth = 0 ;
2005-08-15 16:48:45 +08:00
static GimpPageSelectorTarget ps_pagemode = GIMP_PAGE_SELECTOR_TARGET_LAYERS ;
2000-01-23 06:26:20 +08:00
static void
ascii85_init ( void )
{
2000-01-26 01:46:56 +08:00
ascii85_len = 0 ;
ascii85_linewidth = 0 ;
2000-01-23 06:26:20 +08:00
}
static void
ascii85_flush ( FILE * ofp )
{
2000-01-26 01:46:56 +08:00
char c [ 5 ] ;
int i ;
gboolean zero_case = ( ascii85_buf = = 0 ) ;
2000-03-26 06:19:17 +08:00
static int max_linewidth = 75 ;
2000-01-23 06:26:20 +08:00
2000-01-26 01:46:56 +08:00
for ( i = 4 ; i > = 0 ; i - - )
2000-01-23 06:26:20 +08:00
{
2000-01-26 01:46:56 +08:00
c [ i ] = ( ascii85_buf % 85 ) + ' ! ' ;
ascii85_buf / = 85 ;
2000-01-23 06:26:20 +08:00
}
2000-01-26 01:46:56 +08:00
/* check for special case: "!!!!!" becomes "z", but only if not
* at end of data . */
if ( zero_case & & ( ascii85_len = = 4 ) )
2000-01-23 06:26:20 +08:00
{
2000-03-26 06:19:17 +08:00
if ( ascii85_linewidth > = max_linewidth )
{
putc ( ' \n ' , ofp ) ;
ascii85_linewidth = 0 ;
}
2000-01-26 01:46:56 +08:00
putc ( ' z ' , ofp ) ;
ascii85_linewidth + + ;
2000-01-23 06:26:20 +08:00
}
2000-01-26 01:46:56 +08:00
else
2000-01-23 06:26:20 +08:00
{
2000-01-26 01:46:56 +08:00
for ( i = 0 ; i < ascii85_len + 1 ; i + + )
2000-03-26 06:19:17 +08:00
{
if ( ( ascii85_linewidth > = max_linewidth ) & & ( c [ i ] ! = ' % ' ) )
{
putc ( ' \n ' , ofp ) ;
ascii85_linewidth = 0 ;
}
2006-05-08 20:23:32 +08:00
putc ( c [ i ] , ofp ) ;
2000-03-26 06:19:17 +08:00
ascii85_linewidth + + ;
}
2000-01-23 06:26:20 +08:00
}
2000-01-26 01:46:56 +08:00
ascii85_len = 0 ;
ascii85_buf = 0 ;
2000-01-23 06:26:20 +08:00
}
static inline void
ascii85_out ( unsigned char byte , FILE * ofp )
{
2000-01-26 01:46:56 +08:00
if ( ascii85_len = = 4 )
ascii85_flush ( ofp ) ;
2000-01-23 06:26:20 +08:00
2000-01-26 01:46:56 +08:00
ascii85_buf < < = 8 ;
ascii85_buf | = byte ;
ascii85_len + + ;
2000-01-23 06:26:20 +08:00
}
2000-03-11 01:27:25 +08:00
static void
ascii85_nout ( int n , unsigned char * uptr , FILE * ofp )
{
while ( n - - > 0 )
{
ascii85_out ( * uptr , ofp ) ;
uptr + + ;
}
}
2000-01-23 06:26:20 +08:00
static void
ascii85_done ( FILE * ofp )
{
2000-01-26 01:46:56 +08:00
if ( ascii85_len )
2000-01-23 06:26:20 +08:00
{
2000-01-26 01:46:56 +08:00
/* zero any unfilled buffer portion, then flush */
ascii85_buf < < = ( 8 * ( 4 - ascii85_len ) ) ;
ascii85_flush ( ofp ) ;
2000-01-23 06:26:20 +08:00
}
2000-01-26 01:46:56 +08:00
putc ( ' ~ ' , ofp ) ;
putc ( ' > ' , ofp ) ;
putc ( ' \n ' , ofp ) ;
2000-01-23 06:26:20 +08:00
}
2000-03-11 01:27:25 +08:00
static void
compress_packbits ( int nin ,
unsigned char * src ,
int * nout ,
unsigned char * dst )
{ register unsigned char c ;
int nrepeat , nliteral ;
unsigned char * run_start ;
unsigned char * start_dst = dst ;
unsigned char * last_literal = NULL ;
for ( ; ; )
{
if ( nin < = 0 ) break ;
run_start = src ;
c = * run_start ;
/* Search repeat bytes */
if ( ( nin > 1 ) & & ( c = = src [ 1 ] ) )
{
nrepeat = 1 ;
nin - = 2 ;
src + = 2 ;
while ( ( nin > 0 ) & & ( c = = * src ) )
{
nrepeat + + ;
src + + ;
nin - - ;
if ( nrepeat = = 127 ) break ; /* Maximum repeat */
}
/* Add two-byte repeat to last literal run ? */
if ( ( nrepeat = = 1 )
& & ( last_literal ! = NULL ) & & ( ( ( * last_literal ) + 1 ) + 2 < = 128 ) )
{
* last_literal + = 2 ;
* ( dst + + ) = c ;
* ( dst + + ) = c ;
continue ;
}
/* Add repeat run */
* ( dst + + ) = ( unsigned char ) ( ( - nrepeat ) & 0xff ) ;
* ( dst + + ) = c ;
last_literal = NULL ;
continue ;
}
/* Search literal bytes */
nliteral = 1 ;
nin - - ;
src + + ;
for ( ; ; )
{
if ( nin < = 0 ) break ;
if ( ( nin > = 2 ) & & ( src [ 0 ] = = src [ 1 ] ) ) /* A two byte repeat ? */
break ;
nliteral + + ;
nin - - ;
src + + ;
if ( nliteral = = 128 ) break ; /* Maximum literal run */
}
/* Could be added to last literal run ? */
if ( ( last_literal ! = NULL ) & & ( ( ( * last_literal ) + 1 ) + nliteral < = 128 ) )
{
* last_literal + = nliteral ;
}
else
{
last_literal = dst ;
* ( dst + + ) = ( unsigned char ) ( nliteral - 1 ) ;
}
while ( nliteral - - > 0 ) * ( dst + + ) = * ( run_start + + ) ;
}
* nout = dst - start_dst ;
}
2000-01-23 06:26:20 +08:00
2000-04-05 18:26:08 +08:00
typedef struct
{
long eol ;
long begin_data ;
} PS_DATA_POS ;
static PS_DATA_POS ps_data_pos = { 0 , 0 } ;
static void
ps_begin_data ( FILE * ofp )
{
/* %%BeginData: 123456789012 ASCII Bytes */
fprintf ( ofp , " %s " , " %%BeginData: " ) ;
fflush ( ofp ) ;
ps_data_pos . eol = ftell ( ofp ) ;
fprintf ( ofp , " \n " ) ;
fflush ( ofp ) ;
ps_data_pos . begin_data = ftell ( ofp ) ;
}
static void
ps_end_data ( FILE * ofp )
{ long end_data ;
char s [ 64 ] ;
if ( ( ps_data_pos . begin_data > 0 ) & & ( ps_data_pos . eol > 0 ) )
{
fflush ( ofp ) ;
end_data = ftell ( ofp ) ;
if ( end_data > 0 )
{
2006-08-29 21:32:22 +08:00
sprintf ( s , " %ld ASCII Bytes " , end_data - ps_data_pos . begin_data ) ;
2000-04-05 18:26:08 +08:00
if ( fseek ( ofp , ps_data_pos . eol - strlen ( s ) , SEEK_SET ) = = 0 )
{
fprintf ( ofp , " %s " , s ) ;
fseek ( ofp , 0 , SEEK_END ) ;
}
}
}
fprintf ( ofp , " %s \n " , " %%EndData " ) ;
}
1997-11-25 06:05:25 +08:00
MAIN ( )
static void
query ( void )
{
2006-05-16 20:26:20 +08:00
static const GimpParamDef load_args [ ] =
1997-11-25 06:05:25 +08:00
{
2005-08-15 18:30:39 +08:00
{ GIMP_PDB_INT32 , " run-mode " , " Interactive, non-interactive " } ,
{ GIMP_PDB_STRING , " filename " , " The name of the file to load " } ,
{ GIMP_PDB_STRING , " raw-filename " , " The name of the file to load " }
1997-11-25 06:05:25 +08:00
} ;
2006-05-16 20:26:20 +08:00
static const GimpParamDef load_return_vals [ ] =
1997-11-25 06:05:25 +08:00
{
2004-11-19 03:00:02 +08:00
{ GIMP_PDB_IMAGE , " image " , " Output image " }
1997-11-25 06:05:25 +08:00
} ;
2006-05-16 20:26:20 +08:00
static const GimpParamDef set_load_args [ ] =
1997-11-25 06:05:25 +08:00
{
2005-08-15 18:30:39 +08:00
{ GIMP_PDB_INT32 , " resolution " , " Resolution to interprete image (dpi) " } ,
{ GIMP_PDB_INT32 , " width " , " Desired width " } ,
{ GIMP_PDB_INT32 , " height " , " Desired height " } ,
{ GIMP_PDB_INT32 , " check-bbox " , " 0: Use width/height, 1: Use BoundingBox " } ,
{ GIMP_PDB_STRING , " pages " , " Pages to load (e.g.: 1,3,5-7) " } ,
{ GIMP_PDB_INT32 , " coloring " , " 4: b/w, 5: grey, 6: colour image, 7: automatic " } ,
{ GIMP_PDB_INT32 , " TextAlphaBits " , " 1, 2, or 4 " } ,
{ GIMP_PDB_INT32 , " GraphicsAlphaBits " , " 1, 2, or 4 " }
1997-11-25 06:05:25 +08:00
} ;
2006-05-16 20:26:20 +08:00
static const GimpParamDef thumb_args [ ] =
2004-11-19 03:00:02 +08:00
{
{ GIMP_PDB_STRING , " filename " , " The name of the file to load " } ,
2005-08-15 18:30:39 +08:00
{ GIMP_PDB_INT32 , " thumb-size " , " Preferred thumbnail size " }
2004-11-19 03:00:02 +08:00
} ;
2006-05-16 20:26:20 +08:00
static const GimpParamDef thumb_return_vals [ ] =
2004-11-19 03:00:02 +08:00
{
{ GIMP_PDB_IMAGE , " image " , " Output image " }
} ;
2006-05-16 20:26:20 +08:00
static const GimpParamDef save_args [ ] =
1997-11-25 06:05:25 +08:00
{
2005-08-15 18:30:39 +08:00
{ GIMP_PDB_INT32 , " run-mode " , " Interactive, non-interactive " } ,
{ GIMP_PDB_IMAGE , " image " , " Input image " } ,
{ GIMP_PDB_DRAWABLE , " drawable " , " Drawable to save " } ,
{ GIMP_PDB_STRING , " filename " , " The name of the file to save the image in " } ,
{ GIMP_PDB_STRING , " raw-filename " , " The name of the file to save the image in " } ,
{ GIMP_PDB_FLOAT , " width " , " Width of the image in PostScript file (0: use input image size) " } ,
{ GIMP_PDB_FLOAT , " height " , " Height of image in PostScript file (0: use input image size) " } ,
{ GIMP_PDB_FLOAT , " x-offset " , " X-offset to image from lower left corner " } ,
{ GIMP_PDB_FLOAT , " y-offset " , " Y-offset to image from lower left corner " } ,
{ GIMP_PDB_INT32 , " unit " , " Unit for width/height/offset. 0: inches, 1: millimeters " } ,
{ GIMP_PDB_INT32 , " keep-ratio " , " 0: use width/height, 1: keep aspect ratio " } ,
{ GIMP_PDB_INT32 , " rotation " , " 0, 90, 180, 270 " } ,
{ GIMP_PDB_INT32 , " eps-flag " , " 0: PostScript, 1: Encapsulated PostScript " } ,
{ GIMP_PDB_INT32 , " preview " , " 0: no preview, >0: max. size of preview " } ,
{ GIMP_PDB_INT32 , " level " , " 1: PostScript Level 1, 2: PostScript Level 2 " }
1997-11-25 06:05:25 +08:00
} ;
2005-08-15 18:30:39 +08:00
gimp_install_procedure ( LOAD_PS_PROC ,
2004-05-14 08:01:11 +08:00
" load PostScript documents " ,
" load PostScript documents " ,
1999-09-15 04:54:02 +08:00
" Peter Kirchgessner <peter@kirchgessner.net> " ,
1997-11-25 06:05:25 +08:00
" Peter Kirchgessner " ,
1997-12-26 15:08:20 +08:00
dversio ,
2004-05-14 08:01:11 +08:00
N_ ( " PostScript document " ) ,
1997-11-25 06:05:25 +08:00
NULL ,
2000-08-22 09:26:57 +08:00
GIMP_PLUGIN ,
2001-12-06 10:28:58 +08:00
G_N_ELEMENTS ( load_args ) ,
G_N_ELEMENTS ( load_return_vals ) ,
1997-11-25 06:05:25 +08:00
load_args , load_return_vals ) ;
2005-08-15 18:30:39 +08:00
gimp_register_file_handler_mime ( LOAD_PS_PROC , " application/postscript " ) ;
gimp_register_magic_load_handler ( LOAD_PS_PROC ,
2006-05-08 20:23:32 +08:00
" ps " ,
" " ,
2004-05-14 08:01:11 +08:00
" 0,string,%!,0,long,0xc5d0d3c6 " ) ;
2005-08-15 18:30:39 +08:00
gimp_install_procedure ( LOAD_EPS_PROC ,
2004-05-14 08:01:11 +08:00
" load Encapsulated PostScript images " ,
" load Encapsulated PostScript images " ,
" Peter Kirchgessner <peter@kirchgessner.net> " ,
" Peter Kirchgessner " ,
dversio ,
N_ ( " Encapsulated PostScript image " ) ,
NULL ,
GIMP_PLUGIN ,
G_N_ELEMENTS ( load_args ) ,
G_N_ELEMENTS ( load_return_vals ) ,
load_args , load_return_vals ) ;
2005-08-15 18:30:39 +08:00
gimp_register_file_handler_mime ( LOAD_EPS_PROC , " image/x-eps " ) ;
gimp_register_magic_load_handler ( LOAD_EPS_PROC ,
2006-05-08 20:23:32 +08:00
" eps " ,
" " ,
2004-05-14 08:01:11 +08:00
" 0,string,%!,0,long,0xc5d0d3c6 " ) ;
2005-07-03 03:58:49 +08:00
# ifndef HAVE_POPPLER
2005-08-15 18:30:39 +08:00
gimp_install_procedure ( LOAD_PDF_PROC ,
2004-05-14 08:01:11 +08:00
" load PDF documents " ,
" load PDF documents " ,
" Peter Kirchgessner <peter@kirchgessner.net> " ,
" Peter Kirchgessner " ,
dversio ,
N_ ( " PDF document " ) ,
NULL ,
GIMP_PLUGIN ,
G_N_ELEMENTS ( load_args ) ,
G_N_ELEMENTS ( load_return_vals ) ,
load_args , load_return_vals ) ;
2005-08-15 18:30:39 +08:00
gimp_register_file_handler_mime ( LOAD_PDF_PROC , " application/pdf " ) ;
gimp_register_magic_load_handler ( LOAD_PDF_PROC ,
2006-05-08 20:23:32 +08:00
" pdf " ,
" " ,
2004-05-14 08:01:11 +08:00
" 0,string,%PDF " ) ;
2005-07-03 03:58:49 +08:00
# endif
2004-05-14 08:01:11 +08:00
2005-08-15 18:30:39 +08:00
gimp_install_procedure ( LOAD_PS_SETARGS_PROC ,
2006-08-29 21:32:22 +08:00
" set additional parameters for procedure file-ps-load " ,
" set additional parameters for procedure file-ps-load " ,
1999-09-15 04:54:02 +08:00
" Peter Kirchgessner <peter@kirchgessner.net> " ,
1997-11-25 06:05:25 +08:00
" Peter Kirchgessner " ,
1997-12-26 15:08:20 +08:00
dversio ,
1997-11-25 06:05:25 +08:00
NULL ,
NULL ,
2000-08-22 09:26:57 +08:00
GIMP_PLUGIN ,
2001-12-06 10:28:58 +08:00
G_N_ELEMENTS ( set_load_args ) , 0 ,
1997-11-25 06:05:25 +08:00
set_load_args , NULL ) ;
2005-08-15 18:30:39 +08:00
gimp_install_procedure ( LOAD_PS_THUMB_PROC ,
2006-08-29 21:32:22 +08:00
" Loads a small preview from a PostScript or PDF document " ,
2004-11-19 03:00:02 +08:00
" " ,
" Peter Kirchgessner <peter@kirchgessner.net> " ,
" Peter Kirchgessner " ,
dversio ,
2006-05-08 20:23:32 +08:00
NULL ,
NULL ,
2004-11-19 03:00:02 +08:00
GIMP_PLUGIN ,
G_N_ELEMENTS ( thumb_args ) ,
G_N_ELEMENTS ( thumb_return_vals ) ,
thumb_args , thumb_return_vals ) ;
2005-08-15 18:30:39 +08:00
gimp_register_thumbnail_loader ( LOAD_PS_PROC , LOAD_PS_THUMB_PROC ) ;
gimp_register_thumbnail_loader ( LOAD_EPS_PROC , LOAD_PS_THUMB_PROC ) ;
2005-07-03 03:58:49 +08:00
# ifndef HAVE_POPPLER
2005-08-15 18:30:39 +08:00
gimp_register_thumbnail_loader ( LOAD_PDF_PROC , LOAD_PS_THUMB_PROC ) ;
2005-07-03 03:58:49 +08:00
# endif
2004-11-19 03:00:02 +08:00
2005-08-15 18:30:39 +08:00
gimp_install_procedure ( SAVE_PS_PROC ,
2004-05-14 08:01:11 +08:00
" save image as PostScript docuement " ,
2005-08-15 18:30:39 +08:00
" PostScript saving handles all image types except "
" those with alpha channels. " ,
2000-03-11 01:27:25 +08:00
" Peter Kirchgessner <peter@kirchgessner.net> " ,
1997-11-25 06:05:25 +08:00
" Peter Kirchgessner " ,
1997-12-26 15:08:20 +08:00
dversio ,
2004-05-14 08:01:11 +08:00
N_ ( " PostScript document " ) ,
1999-10-04 02:54:54 +08:00
" RGB, GRAY, INDEXED " ,
2000-08-22 09:26:57 +08:00
GIMP_PLUGIN ,
2001-12-06 10:28:58 +08:00
G_N_ELEMENTS ( save_args ) , 0 ,
1997-11-25 06:05:25 +08:00
save_args , NULL ) ;
2005-08-15 18:30:39 +08:00
gimp_register_file_handler_mime ( SAVE_PS_PROC , " application/postscript " ) ;
gimp_register_save_handler ( SAVE_PS_PROC , " ps " , " " ) ;
2004-05-14 08:01:11 +08:00
2005-08-15 18:30:39 +08:00
gimp_install_procedure ( SAVE_EPS_PROC ,
2004-05-14 08:01:11 +08:00
" save image as Encapsulated PostScript image " ,
2005-08-15 18:30:39 +08:00
" PostScript saving handles all image types except "
" those with alpha channels. " ,
2004-05-14 08:01:11 +08:00
" Peter Kirchgessner <peter@kirchgessner.net> " ,
" Peter Kirchgessner " ,
dversio ,
N_ ( " Encapsulated PostScript image " ) ,
" RGB, GRAY, INDEXED " ,
GIMP_PLUGIN ,
G_N_ELEMENTS ( save_args ) , 0 ,
save_args , NULL ) ;
2005-08-15 18:30:39 +08:00
gimp_register_file_handler_mime ( SAVE_EPS_PROC , " application/x-eps " ) ;
gimp_register_save_handler ( SAVE_EPS_PROC , " eps " , " " ) ;
1997-11-25 06:05:25 +08:00
}
1999-09-15 04:54:02 +08:00
static void
ps_set_save_size ( PSSaveVals * vals ,
2000-01-26 01:46:56 +08:00
gint32 image_ID )
{
2000-02-08 04:35:13 +08:00
gdouble xres , yres , factor , iw , ih ;
guint width , height ;
GimpUnit unit ;
1999-09-15 04:54:02 +08:00
gimp_image_get_resolution ( image_ID , & xres , & yres ) ;
2000-03-26 06:19:17 +08:00
if ( ( xres < 1e-5 ) | | ( yres < 1e-5 ) )
2000-01-26 01:46:56 +08:00
{
xres = yres = 72.0 ;
}
1999-09-15 04:54:02 +08:00
/* Calculate size of image in inches */
2000-01-26 01:46:56 +08:00
width = gimp_image_width ( image_ID ) ;
1999-09-15 04:54:02 +08:00
height = gimp_image_height ( image_ID ) ;
2000-01-26 01:46:56 +08:00
iw = width / xres ;
ih = height / yres ;
unit = gimp_image_get_unit ( image_ID ) ;
factor = gimp_unit_get_factor ( unit ) ;
if ( factor = = 0.0254 | |
factor = = 0.254 | |
factor = = 2.54 | |
factor = = 25.4 )
{
vals - > unit_mm = TRUE ;
}
1999-09-15 04:54:02 +08:00
if ( vals - > unit_mm )
2000-01-26 01:46:56 +08:00
{
iw * = 25.4 ;
ih * = 25.4 ;
}
vals - > width = iw ;
1999-09-15 04:54:02 +08:00
vals - > height = ih ;
}
1997-11-25 06:05:25 +08:00
static void
2003-07-02 20:03:08 +08:00
run ( const gchar * name ,
gint nparams ,
const GimpParam * param ,
gint * nreturn_vals ,
GimpParam * * return_vals )
1997-11-25 06:05:25 +08:00
{
2003-11-06 23:27:05 +08:00
static GimpParam values [ 2 ] ;
GimpRunMode run_mode ;
GimpPDBStatusType status = GIMP_PDB_SUCCESS ;
gint32 image_ID = - 1 ;
gint32 drawable_ID = - 1 ;
gint32 orig_image_ID = - 1 ;
GimpExportReturn export = GIMP_EXPORT_CANCEL ;
1997-11-25 06:05:25 +08:00
l_run_mode = run_mode = param [ 0 ] . data . d_int32 ;
2003-03-26 00:38:19 +08:00
INIT_I18N ( ) ;
1997-11-25 06:05:25 +08:00
* nreturn_vals = 1 ;
2000-01-26 01:46:56 +08:00
* return_vals = values ;
2004-11-19 03:00:02 +08:00
2000-08-22 09:26:57 +08:00
values [ 0 ] . type = GIMP_PDB_STATUS ;
values [ 0 ] . data . d_status = GIMP_PDB_EXECUTION_ERROR ;
1997-11-25 06:05:25 +08:00
2005-08-15 18:30:39 +08:00
if ( strcmp ( name , LOAD_PS_PROC ) = = 0 | |
strcmp ( name , LOAD_EPS_PROC ) = = 0 | |
strcmp ( name , LOAD_PDF_PROC ) = = 0 )
1997-11-25 06:05:25 +08:00
{
switch ( run_mode )
2006-05-08 20:23:32 +08:00
{
2000-08-22 09:26:57 +08:00
case GIMP_RUN_INTERACTIVE :
1997-11-25 06:05:25 +08:00
/* Possibly retrieve data */
2005-08-15 18:30:39 +08:00
gimp_get_data ( LOAD_PS_PROC , & plvals ) ;
1997-11-25 06:05:25 +08:00
2005-08-15 16:48:45 +08:00
if ( ! load_dialog ( param [ 1 ] . data . d_string ,
2005-08-15 18:30:39 +08:00
! strcmp ( name , LOAD_PDF_PROC ) ) )
2006-05-08 20:23:32 +08:00
status = GIMP_PDB_CANCEL ;
1997-11-25 06:05:25 +08:00
break ;
2000-08-22 09:26:57 +08:00
case GIMP_RUN_NONINTERACTIVE :
1997-11-25 06:05:25 +08:00
/* Make sure all the arguments are there! */
if ( nparams ! = 3 )
2000-08-22 09:26:57 +08:00
status = GIMP_PDB_CALLING_ERROR ;
1997-11-25 06:05:25 +08:00
else /* Get additional interpretation arguments */
2005-08-15 18:30:39 +08:00
gimp_get_data ( LOAD_PS_PROC , & plvals ) ;
1997-11-25 06:05:25 +08:00
break ;
2000-08-22 09:26:57 +08:00
case GIMP_RUN_WITH_LAST_VALS :
1997-11-25 06:05:25 +08:00
/* Possibly retrieve data */
2005-08-15 18:30:39 +08:00
gimp_get_data ( LOAD_PS_PROC , & plvals ) ;
1997-11-25 06:05:25 +08:00
break ;
default :
break ;
2006-05-08 20:23:32 +08:00
}
2000-01-26 01:46:56 +08:00
2000-08-22 09:26:57 +08:00
if ( status = = GIMP_PDB_SUCCESS )
2006-05-08 20:23:32 +08:00
{
check_load_vals ( ) ;
image_ID = load_image ( param [ 1 ] . data . d_string ) ;
if ( image_ID ! = - 1 )
{
* nreturn_vals = 2 ;
values [ 1 ] . type = GIMP_PDB_IMAGE ;
values [ 1 ] . data . d_image = image_ID ;
}
else
{
status = GIMP_PDB_EXECUTION_ERROR ;
}
}
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
/* Store plvals data */
2000-08-22 09:26:57 +08:00
if ( status = = GIMP_PDB_SUCCESS )
2006-05-08 20:23:32 +08:00
gimp_set_data ( LOAD_PS_PROC , & plvals , sizeof ( PSLoadVals ) ) ;
1997-11-25 06:05:25 +08:00
}
2005-08-15 18:30:39 +08:00
else if ( strcmp ( name , LOAD_PS_THUMB_PROC ) = = 0 )
2004-11-19 03:00:02 +08:00
{
if ( nparams < 2 )
{
status = GIMP_PDB_CALLING_ERROR ;
}
else
{
2004-11-19 05:10:12 +08:00
gint size = param [ 1 ] . data . d_int32 ;
2004-11-19 03:00:02 +08:00
/* We should look for an embedded preview but for now we
* just load the document at a small resolution and the
* first page only .
*/
2004-11-19 05:10:12 +08:00
plvals . resolution = size / 4 ;
2004-11-19 03:00:02 +08:00
plvals . width = size ;
plvals . height = size ;
strcpy ( plvals . pages , " 1 " ) ;
check_load_vals ( ) ;
image_ID = load_image ( param [ 0 ] . data . d_string ) ;
if ( image_ID ! = - 1 )
{
2006-05-08 20:23:32 +08:00
* nreturn_vals = 2 ;
values [ 1 ] . type = GIMP_PDB_IMAGE ;
values [ 1 ] . data . d_image = image_ID ;
2004-11-19 03:00:02 +08:00
}
else
{
status = GIMP_PDB_EXECUTION_ERROR ;
}
}
}
2005-08-15 18:30:39 +08:00
else if ( strcmp ( name , SAVE_PS_PROC ) = = 0 | |
strcmp ( name , SAVE_EPS_PROC ) = = 0 )
1997-11-25 06:05:25 +08:00
{
2005-08-15 18:30:39 +08:00
psvals . eps = strcmp ( name , SAVE_PS_PROC ) ;
2004-05-14 08:01:11 +08:00
1999-10-04 02:54:54 +08:00
image_ID = orig_image_ID = param [ 1 ] . data . d_int32 ;
drawable_ID = param [ 2 ] . data . d_int32 ;
2000-03-11 01:27:25 +08:00
/* eventually export the image */
1999-10-04 02:54:54 +08:00
switch ( run_mode )
2006-05-08 20:23:32 +08:00
{
case GIMP_RUN_INTERACTIVE :
case GIMP_RUN_WITH_LAST_VALS :
gimp_ui_init ( PLUG_IN_BINARY , FALSE ) ;
export = gimp_export_image ( & image_ID , & drawable_ID ,
2004-05-14 08:01:11 +08:00
psvals . eps ? " EPS " : " PostScript " ,
2006-05-08 20:23:32 +08:00
( GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_INDEXED ) ) ;
if ( export = = GIMP_EXPORT_CANCEL )
{
values [ 0 ] . data . d_status = GIMP_PDB_CANCEL ;
return ;
}
break ;
default :
break ;
}
1999-10-04 02:54:54 +08:00
1997-11-25 06:05:25 +08:00
switch ( run_mode )
{
2000-08-22 09:26:57 +08:00
case GIMP_RUN_INTERACTIVE :
1997-11-25 06:05:25 +08:00
/* Possibly retrieve data */
2004-05-14 08:01:11 +08:00
gimp_get_data ( name , & psvals ) ;
1997-12-26 15:08:20 +08:00
1999-10-04 02:54:54 +08:00
ps_set_save_size ( & psvals , orig_image_ID ) ;
2001-05-22 08:36:38 +08:00
1997-11-25 06:05:25 +08:00
/* First acquire information with a dialog */
if ( ! save_dialog ( ) )
2000-08-22 09:26:57 +08:00
status = GIMP_PDB_CANCEL ;
1997-11-25 06:05:25 +08:00
break ;
2000-08-22 09:26:57 +08:00
case GIMP_RUN_NONINTERACTIVE :
1997-11-25 06:05:25 +08:00
/* Make sure all the arguments are there! */
2000-01-23 06:26:20 +08:00
if ( nparams ! = 15 )
2006-05-08 20:23:32 +08:00
{
status = GIMP_PDB_CALLING_ERROR ;
}
1997-11-25 06:05:25 +08:00
else
2006-05-08 20:23:32 +08:00
{
psvals . width = param [ 5 ] . data . d_float ;
psvals . height = param [ 6 ] . data . d_float ;
psvals . x_offset = param [ 7 ] . data . d_float ;
psvals . y_offset = param [ 8 ] . data . d_float ;
psvals . unit_mm = ( param [ 9 ] . data . d_int32 ! = 0 ) ;
psvals . keep_ratio = ( param [ 10 ] . data . d_int32 ! = 0 ) ;
psvals . rotate = param [ 11 ] . data . d_int32 ;
psvals . eps = param [ 12 ] . data . d_int32 ;
psvals . preview = ( param [ 13 ] . data . d_int32 ! = 0 ) ;
psvals . preview_size = param [ 13 ] . data . d_int32 ;
psvals . level = param [ 14 ] . data . d_int32 ;
}
1997-11-25 06:05:25 +08:00
break ;
2000-08-22 09:26:57 +08:00
case GIMP_RUN_WITH_LAST_VALS :
1997-11-25 06:05:25 +08:00
/* Possibly retrieve data */
2004-05-14 08:01:11 +08:00
gimp_get_data ( name , & psvals ) ;
1997-11-25 06:05:25 +08:00
break ;
default :
break ;
}
2000-08-22 09:26:57 +08:00
if ( status = = GIMP_PDB_SUCCESS )
2006-05-08 20:23:32 +08:00
{
if ( ( psvals . width = = 0.0 ) | | ( psvals . height = = 0.0 ) )
ps_set_save_size ( & psvals , orig_image_ID ) ;
check_save_vals ( ) ;
if ( save_image ( param [ 3 ] . data . d_string , image_ID , drawable_ID ) )
{
/* Store psvals data */
gimp_set_data ( name , & psvals , sizeof ( PSSaveVals ) ) ;
}
else
{
status = GIMP_PDB_EXECUTION_ERROR ;
}
}
1999-10-04 02:54:54 +08:00
2000-08-24 22:17:34 +08:00
if ( export = = GIMP_EXPORT_EXPORT )
2006-05-08 20:23:32 +08:00
gimp_image_delete ( image_ID ) ;
1997-11-25 06:05:25 +08:00
}
2005-08-15 18:30:39 +08:00
else if ( strcmp ( name , LOAD_PS_SETARGS_PROC ) = = 0 )
1997-11-25 06:05:25 +08:00
{
/* Make sure all the arguments are there! */
if ( nparams ! = 8 )
2006-05-08 20:23:32 +08:00
{
status = GIMP_PDB_CALLING_ERROR ;
}
1997-11-25 06:05:25 +08:00
else
2006-05-08 20:23:32 +08:00
{
plvals . resolution = param [ 0 ] . data . d_int32 ;
plvals . width = param [ 1 ] . data . d_int32 ;
plvals . height = param [ 2 ] . data . d_int32 ;
plvals . use_bbox = param [ 3 ] . data . d_int32 ;
if ( param [ 4 ] . data . d_string ! = NULL )
strncpy ( plvals . pages , param [ 4 ] . data . d_string ,
sizeof ( plvals . pages ) ) ;
else
plvals . pages [ 0 ] = ' \0 ' ;
plvals . pages [ sizeof ( plvals . pages ) - 1 ] = ' \0 ' ;
plvals . pnm_type = param [ 5 ] . data . d_int32 ;
plvals . textalpha = param [ 6 ] . data . d_int32 ;
plvals . graphicsalpha = param [ 7 ] . data . d_int32 ;
check_load_vals ( ) ;
gimp_set_data ( LOAD_PS_PROC , & plvals , sizeof ( PSLoadVals ) ) ;
}
1997-11-25 06:05:25 +08:00
}
2000-01-26 01:46:56 +08:00
else
{
2000-08-22 09:26:57 +08:00
status = GIMP_PDB_CALLING_ERROR ;
2000-01-26 01:46:56 +08:00
}
values [ 0 ] . data . d_status = status ;
1997-11-25 06:05:25 +08:00
}
static gint32
2003-07-02 20:03:08 +08:00
load_image ( const gchar * filename )
1997-11-25 06:05:25 +08:00
{
2005-08-15 16:48:45 +08:00
gint32 image_ID = 0 ;
gint32 * image_list , * nl ;
guint page_count ;
gint ChildPid ;
FILE * ifp ;
char * temp ;
int llx , lly , urx , ury ;
int k , n_images , max_images , max_pagenum ;
int is_epsf ;
1997-11-25 06:05:25 +08:00
# ifdef PS_DEBUG
2000-01-26 01:46:56 +08:00
g_print ( " load_image: \n resolution = %d \n " , plvals . resolution ) ;
g_print ( " %dx%d pixels \n " , plvals . width , plvals . height ) ;
g_print ( " BoundingBox: %d \n " , plvals . use_bbox ) ;
g_print ( " Colouring: %d \n " , plvals . pnm_type ) ;
g_print ( " TextAlphaBits: %d \n " , plvals . textalpha ) ;
g_print ( " GraphicsAlphaBits: %d \n " , plvals . graphicsalpha ) ;
1997-11-25 06:05:25 +08:00
# endif
2000-01-26 01:46:56 +08:00
/* Try to see if PostScript file is available */
2005-03-04 23:12:29 +08:00
ifp = g_fopen ( filename , " r " ) ;
2000-01-26 01:46:56 +08:00
if ( ifp = = NULL )
{
2003-11-15 21:53:33 +08:00
g_message ( _ ( " Could not open '%s' for reading: %s " ) ,
2004-01-19 11:06:04 +08:00
gimp_filename_to_utf8 ( filename ) , g_strerror ( errno ) ) ;
2003-06-13 22:37:00 +08:00
return - 1 ;
2000-01-26 01:46:56 +08:00
}
fclose ( ifp ) ;
2005-09-30 16:16:10 +08:00
gimp_progress_init_printf ( _ ( " Opening '%s' " ) ,
2005-09-30 02:34:08 +08:00
gimp_filename_to_utf8 ( filename ) ) ;
2000-01-26 01:46:56 +08:00
2004-01-26 07:46:24 +08:00
ifp = ps_open ( filename , & plvals , & llx , & lly , & urx , & ury , & is_epsf ,
& ChildPid ) ;
2000-01-26 01:46:56 +08:00
if ( ! ifp )
{
2004-01-19 11:06:04 +08:00
g_message ( _ ( " Could not interpret '%s' " ) ,
gimp_filename_to_utf8 ( filename ) ) ;
2004-11-19 05:10:12 +08:00
return - 1 ;
2000-01-26 01:46:56 +08:00
}
2001-12-06 10:28:58 +08:00
image_list = g_new ( gint32 , 10 ) ;
2000-01-26 01:46:56 +08:00
n_images = 0 ;
max_images = 10 ;
max_pagenum = 9999 ; /* Try to get the maximum pagenumber to read */
2004-11-19 05:10:12 +08:00
if ( is_epsf )
max_pagenum = 1 ;
2000-01-26 01:46:56 +08:00
if ( ! page_in_list ( plvals . pages , max_pagenum ) ) /* Is there a limit in list ? */
{
max_pagenum = - 1 ;
for ( temp = plvals . pages ; * temp ! = ' \0 ' ; temp + + )
2006-05-08 20:23:32 +08:00
{
if ( ( * temp < ' 0 ' ) | | ( * temp > ' 9 ' ) )
2004-11-19 05:10:12 +08:00
continue ; /* Search next digit */
2006-05-08 20:23:32 +08:00
sscanf ( temp , " %d " , & k ) ;
if ( k > max_pagenum )
2004-11-19 05:10:12 +08:00
max_pagenum = k ;
2006-05-08 20:23:32 +08:00
while ( ( * temp > = ' 0 ' ) & & ( * temp < = ' 9 ' ) )
2004-11-19 05:10:12 +08:00
temp + + ;
2006-05-08 20:23:32 +08:00
temp - - ;
}
2004-11-19 05:10:12 +08:00
if ( max_pagenum < 1 )
max_pagenum = 9999 ;
2000-01-26 01:46:56 +08:00
}
/* Load all images */
for ( page_count = 1 ; page_count < = max_pagenum ; page_count + + )
{
if ( page_in_list ( plvals . pages , page_count ) )
2006-05-08 20:23:32 +08:00
{
image_ID = load_ps ( filename , page_count , ifp , llx , lly , urx , ury ) ;
if ( image_ID = = - 1 )
2004-11-19 05:10:12 +08:00
break ;
2001-05-22 08:36:38 +08:00
2006-05-08 20:23:32 +08:00
gimp_image_set_resolution ( image_ID ,
( double ) plvals . resolution ,
( double ) plvals . resolution ) ;
if ( n_images = = max_images )
{
nl = ( gint32 * ) g_realloc ( image_list ,
( max_images + 10 ) * sizeof ( gint32 ) ) ;
if ( nl = = NULL ) break ;
image_list = nl ;
max_images + = 10 ;
}
image_list [ n_images + + ] = image_ID ;
}
2000-01-26 01:46:56 +08:00
else /* Skip an image */
2006-05-08 20:23:32 +08:00
{
2004-11-19 05:10:12 +08:00
image_ID = - 1 ;
2006-05-08 20:23:32 +08:00
if ( ! skip_ps ( ifp ) )
2004-11-19 05:10:12 +08:00
break ;
2006-05-08 20:23:32 +08:00
}
2000-01-26 01:46:56 +08:00
}
2004-11-19 05:10:12 +08:00
2004-01-26 07:46:24 +08:00
ps_close ( ifp , ChildPid ) ;
2000-01-26 01:46:56 +08:00
2005-08-15 16:48:45 +08:00
if ( ps_pagemode = = GIMP_PAGE_SELECTOR_TARGET_LAYERS )
{
for ( k = 0 ; k < n_images ; k + + )
{
gchar * name ;
if ( k = = 0 )
{
image_ID = image_list [ 0 ] ;
name = g_strdup_printf ( _ ( " %s-pages " ) , filename ) ;
gimp_image_set_filename ( image_ID , name ) ;
g_free ( name ) ;
}
else
{
gint32 current_layer ;
gint32 tmp_ID ;
tmp_ID = gimp_image_get_active_drawable ( image_list [ k ] ) ;
name = gimp_drawable_get_name ( tmp_ID ) ;
current_layer = gimp_layer_new_from_drawable ( tmp_ID , image_ID ) ;
gimp_drawable_set_name ( current_layer , name ) ;
gimp_image_add_layer ( image_ID , current_layer , - 1 ) ;
gimp_image_delete ( image_list [ k ] ) ;
g_free ( name ) ;
}
}
gimp_image_undo_enable ( image_ID ) ;
}
else
2000-01-26 01:46:56 +08:00
{
2005-08-15 16:48:45 +08:00
/* Display images in reverse order.
* The last will be displayed by GIMP itself
*/
for ( k = n_images - 1 ; k > = 0 ; k - - )
{
gimp_image_undo_enable ( image_list [ k ] ) ;
gimp_image_clean_all ( image_list [ k ] ) ;
if ( l_run_mode ! = GIMP_RUN_NONINTERACTIVE & & k > 0 )
gimp_display_new ( image_list [ k ] ) ;
}
image_ID = ( n_images > 0 ) ? image_list [ 0 ] : - 1 ;
2000-01-26 01:46:56 +08:00
}
g_free ( image_list ) ;
2004-11-19 05:10:12 +08:00
return image_ID ;
1997-11-25 06:05:25 +08:00
}
static gint
2003-07-02 20:03:08 +08:00
save_image ( const gchar * filename ,
gint32 image_ID ,
gint32 drawable_ID )
1997-11-25 06:05:25 +08:00
{
FILE * ofp ;
2000-08-22 09:26:57 +08:00
GimpImageType drawable_type ;
1997-11-25 06:05:25 +08:00
gint retval ;
/* initialize */
retval = 0 ;
drawable_type = gimp_drawable_type ( drawable_ID ) ;
/* Make sure we're not saving an image with an alpha channel */
if ( gimp_drawable_has_alpha ( drawable_ID ) )
2000-01-26 01:46:56 +08:00
{
g_message ( _ ( " PostScript save cannot handle images with alpha channels " ) ) ;
return FALSE ;
}
1997-11-25 06:05:25 +08:00
switch ( drawable_type )
2000-01-26 01:46:56 +08:00
{
2000-08-22 09:26:57 +08:00
case GIMP_INDEXED_IMAGE :
case GIMP_GRAY_IMAGE :
case GIMP_RGB_IMAGE :
1997-11-25 06:05:25 +08:00
break ;
default :
2003-11-15 21:53:33 +08:00
g_message ( _ ( " Cannot operate on unknown image types. " ) ) ;
2004-11-19 05:10:12 +08:00
return FALSE ;
1997-11-25 06:05:25 +08:00
break ;
2000-01-26 01:46:56 +08:00
}
1997-11-25 06:05:25 +08:00
/* Open the output file. */
2005-03-04 23:12:29 +08:00
ofp = g_fopen ( filename , " wb " ) ;
1997-11-25 06:05:25 +08:00
if ( ! ofp )
2000-01-26 01:46:56 +08:00
{
2003-11-15 21:53:33 +08:00
g_message ( _ ( " Could not open '%s' for writing: %s " ) ,
2004-01-19 11:06:04 +08:00
gimp_filename_to_utf8 ( filename ) , g_strerror ( errno ) ) ;
2004-11-19 05:10:12 +08:00
return FALSE ;
2000-01-26 01:46:56 +08:00
}
1997-11-25 06:05:25 +08:00
2005-09-30 16:16:10 +08:00
gimp_progress_init_printf ( _ ( " Saving '%s' " ) ,
2005-09-30 02:34:08 +08:00
gimp_filename_to_utf8 ( filename ) ) ;
1997-11-25 06:05:25 +08:00
save_ps_header ( ofp , filename ) ;
2000-08-22 09:26:57 +08:00
if ( drawable_type = = GIMP_GRAY_IMAGE )
1999-10-04 02:54:54 +08:00
retval = save_gray ( ofp , image_ID , drawable_ID ) ;
2000-08-22 09:26:57 +08:00
else if ( drawable_type = = GIMP_INDEXED_IMAGE )
1999-10-04 02:54:54 +08:00
retval = save_index ( ofp , image_ID , drawable_ID ) ;
2000-08-22 09:26:57 +08:00
else if ( drawable_type = = GIMP_RGB_IMAGE )
1999-10-04 02:54:54 +08:00
retval = save_rgb ( ofp , image_ID , drawable_ID ) ;
1997-11-25 06:05:25 +08:00
save_ps_trailer ( ofp ) ;
fclose ( ofp ) ;
2004-11-19 05:10:12 +08:00
return retval ;
1997-11-25 06:05:25 +08:00
}
/* Check (and correct) the load values plvals */
static void
check_load_vals ( void )
{
2000-01-26 01:46:56 +08:00
if ( plvals . resolution < 5 )
plvals . resolution = 5 ;
else if ( plvals . resolution > 1440 )
plvals . resolution = 1440 ;
if ( plvals . width < 2 )
plvals . width = 2 ;
if ( plvals . height < 2 )
plvals . height = 2 ;
1997-11-25 06:05:25 +08:00
plvals . use_bbox = ( plvals . use_bbox ! = 0 ) ;
if ( plvals . pages [ 0 ] = = ' \0 ' )
strcpy ( plvals . pages , " 1-99 " ) ;
if ( ( plvals . pnm_type < 4 ) | | ( plvals . pnm_type > 7 ) )
plvals . pnm_type = 6 ;
if ( ( plvals . textalpha ! = 1 ) & & ( plvals . textalpha ! = 2 )
& & ( plvals . textalpha ! = 4 ) )
plvals . textalpha = 1 ;
if ( ( plvals . graphicsalpha ! = 1 ) & & ( plvals . graphicsalpha ! = 2 )
& & ( plvals . graphicsalpha ! = 4 ) )
plvals . graphicsalpha = 1 ;
}
/* Check (and correct) the save values psvals */
static void
check_save_vals ( void )
2000-01-26 01:46:56 +08:00
{
int i ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
i = psvals . rotate ;
if ( ( i ! = 0 ) & & ( i ! = 90 ) & & ( i ! = 180 ) & & ( i ! = 270 ) )
psvals . rotate = 90 ;
if ( psvals . preview_size < = 0 )
psvals . preview = FALSE ;
1997-11-25 06:05:25 +08:00
}
/* Check if a page is in a given list */
static gint
2000-01-26 01:46:56 +08:00
page_in_list ( gchar * list ,
guint page_num )
{
char tmplist [ STR_LENGTH ] , * c0 , * c1 ;
int state , start_num , end_num ;
1997-11-25 06:05:25 +08:00
# define READ_STARTNUM 0
# define READ_ENDNUM 1
# define CHK_LIST(a,b,c) {int low=(a),high=(b),swp; \
if ( ( low > 0 ) & & ( high > 0 ) ) { \
if ( low > high ) { swp = low ; low = high ; high = swp ; } \
if ( ( low < = ( c ) ) & & ( high > = ( c ) ) ) return ( 1 ) ; } }
2004-11-19 05:10:12 +08:00
if ( ( list = = NULL ) | | ( * list = = ' \0 ' ) )
return 1 ;
2000-01-26 01:46:56 +08:00
strncpy ( tmplist , list , STR_LENGTH ) ;
tmplist [ STR_LENGTH - 1 ] = ' \0 ' ;
c0 = c1 = tmplist ;
while ( * c1 ) /* Remove all whitespace and break on unsupported characters */
{
if ( ( * c1 > = ' 0 ' ) & & ( * c1 < = ' 9 ' ) )
2006-05-08 20:23:32 +08:00
{
* ( c0 + + ) = * c1 ;
}
2000-01-26 01:46:56 +08:00
else if ( ( * c1 = = ' - ' ) | | ( * c1 = = ' , ' ) )
2006-05-08 20:23:32 +08:00
{ /* Try to remove double occurances of these characters */
if ( c0 = = tmplist )
{
* ( c0 + + ) = * c1 ;
}
else
{
if ( * ( c0 - 1 ) ! = * c1 )
* ( c0 + + ) = * c1 ;
}
}
2004-11-19 05:10:12 +08:00
else
break ;
2000-01-26 01:46:56 +08:00
c1 + + ;
}
2004-11-19 05:10:12 +08:00
if ( c0 = = tmplist )
return 1 ;
2000-01-26 01:46:56 +08:00
* c0 = ' \0 ' ;
/* Now we have a comma separated list like 1-4-1,-3,1- */
start_num = end_num = - 1 ;
state = READ_STARTNUM ;
for ( c0 = tmplist ; * c0 ! = ' \0 ' ; c0 + + )
{
switch ( state )
2006-05-08 20:23:32 +08:00
{
case READ_STARTNUM :
if ( * c0 = = ' , ' )
{
if ( ( start_num > 0 ) & & ( start_num = = ( int ) page_num ) )
2004-11-19 05:10:12 +08:00
return - 1 ;
2006-05-08 20:23:32 +08:00
start_num = - 1 ;
}
else if ( * c0 = = ' - ' )
{
if ( start_num < 0 ) start_num = 1 ;
state = READ_ENDNUM ;
}
else /* '0' - '9' */
{
if ( start_num < 0 ) start_num = 0 ;
start_num * = 10 ;
start_num + = * c0 - ' 0 ' ;
}
break ;
case READ_ENDNUM :
if ( * c0 = = ' , ' )
{
if ( end_num < 0 ) end_num = 9999 ;
CHK_LIST ( start_num , end_num , ( int ) page_num ) ;
start_num = end_num = - 1 ;
state = READ_STARTNUM ;
}
else if ( * c0 = = ' - ' )
{
CHK_LIST ( start_num , end_num , ( int ) page_num ) ;
start_num = end_num ;
end_num = - 1 ;
}
else /* '0' - '9' */
{
if ( end_num < 0 ) end_num = 0 ;
end_num * = 10 ;
end_num + = * c0 - ' 0 ' ;
}
break ;
}
2000-01-26 01:46:56 +08:00
}
if ( state = = READ_STARTNUM )
{
if ( start_num > 0 )
2006-05-08 20:23:32 +08:00
return ( start_num = = ( int ) page_num ) ;
2000-01-26 01:46:56 +08:00
}
else
{
if ( end_num < 0 ) end_num = 9999 ;
CHK_LIST ( start_num , end_num , ( int ) page_num ) ;
}
2004-11-19 05:10:12 +08:00
return 0 ;
1997-11-25 06:05:25 +08:00
# undef CHK_LIST
}
2000-08-21 07:26:11 +08:00
/* A function like fgets, but treats single CR-character as line break. */
/* As a line break the newline-character is returned. */
static char * psfgets ( char * s , int size , FILE * stream )
2004-11-19 05:10:12 +08:00
{
int c ;
char * sptr = s ;
2000-08-21 07:26:11 +08:00
2004-11-19 05:10:12 +08:00
if ( size < = 0 )
return NULL ;
2000-08-21 07:26:11 +08:00
2004-11-19 05:10:12 +08:00
if ( size = = 1 )
{
* s = ' \0 ' ;
return NULL ;
}
c = getc ( stream ) ;
if ( c = = EOF )
return NULL ;
for ( ; ; )
{
/* At this point we have space in sptr for at least two characters */
if ( c = = ' \n ' ) /* Got end of line (UNIX line end) ? */
{
* ( sptr + + ) = ' \n ' ;
break ;
}
else if ( c = = ' \r ' ) /* Got a carriage return. Check next charcater */
{
c = getc ( stream ) ;
if ( ( c = = EOF ) | | ( c = = ' \n ' ) ) /* EOF or DOS line end ? */
{
* ( sptr + + ) = ' \n ' ; /* Return UNIX line end */
break ;
}
else /* Single carriage return. Return UNIX line end. */
{
ungetc ( c , stream ) ; /* Save the extra character */
* ( sptr + + ) = ' \n ' ;
break ;
}
}
else /* no line end character */
{
* ( sptr + + ) = ( char ) c ;
size - - ;
}
if ( size = = 1 )
break ; /* Only space for the nul-character ? */
c = getc ( stream ) ;
if ( c = = EOF )
break ;
}
* sptr = ' \0 ' ;
return s ;
2000-08-21 07:26:11 +08:00
}
1997-11-25 06:05:25 +08:00
/* Get the BoundingBox of a PostScript file. On success, 0 is returned. */
/* On failure, -1 is returned. */
static gint
2003-07-02 20:03:08 +08:00
get_bbox ( const gchar * filename ,
gint * x0 ,
gint * y0 ,
gint * x1 ,
gint * y1 )
2000-01-26 01:46:56 +08:00
{
char line [ 1024 ] , * src ;
FILE * ifp ;
int retval = - 1 ;
2005-03-05 02:31:43 +08:00
ifp = g_fopen ( filename , " rb " ) ;
2004-11-19 05:10:12 +08:00
if ( ifp = = NULL )
return - 1 ;
2000-01-26 01:46:56 +08:00
for ( ; ; )
{
2000-08-21 07:26:11 +08:00
if ( psfgets ( line , sizeof ( line ) - 1 , ifp ) = = NULL ) break ;
2000-01-26 01:46:56 +08:00
if ( ( line [ 0 ] ! = ' % ' ) | | ( line [ 1 ] ! = ' % ' ) ) continue ;
src = & ( line [ 2 ] ) ;
while ( ( * src = = ' ' ) | | ( * src = = ' \t ' ) ) src + + ;
if ( strncmp ( src , " BoundingBox " , 11 ) ! = 0 ) continue ;
src + = 11 ;
while ( ( * src = = ' ' ) | | ( * src = = ' \t ' ) | | ( * src = = ' : ' ) ) src + + ;
if ( strncmp ( src , " (atend) " , 7 ) = = 0 ) continue ;
if ( sscanf ( src , " %d%d%d%d " , x0 , y0 , x1 , y1 ) = = 4 )
2006-05-08 20:23:32 +08:00
retval = 0 ;
2000-01-26 01:46:56 +08:00
break ;
}
fclose ( ifp ) ;
2004-11-19 05:10:12 +08:00
return retval ;
1997-11-25 06:05:25 +08:00
}
2000-01-26 01:46:56 +08:00
static gchar * pnmfile ;
1997-11-25 06:05:25 +08:00
/* Open the PostScript file. On failure, NULL is returned. */
/* The filepointer returned will give a PNM-file generated */
/* by the PostScript-interpreter. */
static FILE *
2003-07-02 20:03:08 +08:00
ps_open ( const gchar * filename ,
1997-11-25 06:05:25 +08:00
const PSLoadVals * loadopt ,
2000-01-26 01:46:56 +08:00
gint * llx ,
gint * lly ,
gint * urx ,
2000-03-11 01:27:25 +08:00
gint * ury ,
2004-01-26 07:46:24 +08:00
gint * is_epsf ,
gint * ChildPidPtr )
2000-01-26 01:46:56 +08:00
{
2005-03-04 23:12:29 +08:00
const gchar * gs ;
gchar * driver ;
2004-01-26 07:46:24 +08:00
GPtrArray * cmdA ;
gchar * * pcmdA ;
FILE * fd_popen = NULL ;
FILE * eps_file ;
2000-01-26 01:46:56 +08:00
int width , height , resolution ;
int x0 , y0 , x1 , y1 ;
2000-03-26 06:19:17 +08:00
int offx = 0 , offy = 0 ;
2002-05-15 04:04:29 +08:00
int is_pdf , maybe_epsf = 0 ;
2004-01-26 07:46:24 +08:00
GError * Gerr = NULL ;
GSpawnFlags Gflags ;
# ifndef USE_REAL_OUTPUTFILE
gint ChildStdout ;
# endif
2000-01-26 01:46:56 +08:00
2004-01-26 07:46:24 +08:00
* ChildPidPtr = 0 ;
2000-01-26 01:46:56 +08:00
resolution = loadopt - > resolution ;
* llx = * lly = 0 ;
width = loadopt - > width ;
height = loadopt - > height ;
2004-01-26 07:46:24 +08:00
* urx = width - 1 ;
* ury = height - 1 ;
2000-01-26 01:46:56 +08:00
/* Check if the file is a PDF. For PDF, we cant set geometry */
is_pdf = 0 ;
2004-01-26 07:46:24 +08:00
2000-03-11 01:27:25 +08:00
/* Check if it is a EPS-file */
* is_epsf = 0 ;
2004-01-26 07:46:24 +08:00
2005-03-04 23:12:29 +08:00
eps_file = g_fopen ( filename , " rb " ) ;
2004-01-26 07:46:24 +08:00
if ( eps_file ! = NULL )
2000-01-26 01:46:56 +08:00
{
2000-03-11 01:27:25 +08:00
char hdr [ 512 ] ;
2000-01-26 01:46:56 +08:00
2004-01-26 07:46:24 +08:00
fread ( hdr , 1 , sizeof ( hdr ) , eps_file ) ;
2000-01-26 01:46:56 +08:00
is_pdf = ( strncmp ( hdr , " %PDF " , 4 ) = = 0 ) ;
2000-03-11 01:27:25 +08:00
if ( ! is_pdf ) /* Check for EPSF */
2004-01-26 07:46:24 +08:00
{
char * adobe , * epsf ;
int ds = 0 ;
static unsigned char doseps [ 5 ] = { 0xc5 , 0xd0 , 0xd3 , 0xc6 , 0 } ;
hdr [ sizeof ( hdr ) - 1 ] = ' \0 ' ;
adobe = strstr ( hdr , " PS-Adobe- " ) ;
epsf = strstr ( hdr , " EPSF- " ) ;
if ( ( adobe ! = NULL ) & & ( epsf ! = NULL ) )
ds = epsf - adobe ;
* is_epsf = ( ( ds > = 11 ) & & ( ds < = 15 ) ) ;
/* Illustrator uses negative values in BoundingBox without marking */
/* files as EPSF. Try to handle that. */
maybe_epsf =
( strstr ( hdr , " %%Creator: Adobe Illustrator(R) 8.0 " ) ! = 0 ) ;
/* Check DOS EPS binary file */
if ( ( ! * is_epsf ) & & ( strncmp ( hdr , ( char * ) doseps , 4 ) = = 0 ) )
* is_epsf = 1 ;
}
fclose ( eps_file ) ;
2000-01-26 01:46:56 +08:00
}
if ( ( ! is_pdf ) & & ( loadopt - > use_bbox ) ) /* Try the BoundingBox ? */
{
2000-03-26 06:19:17 +08:00
if ( get_bbox ( filename , & x0 , & y0 , & x1 , & y1 ) = = 0 )
{
2002-05-15 04:04:29 +08:00
if ( maybe_epsf & & ( ( x0 < 0 ) | | ( y0 < 0 ) ) )
* is_epsf = 1 ;
2000-03-26 06:19:17 +08:00
if ( * is_epsf ) /* Handle negative BoundingBox for EPSF */
{
offx = - x0 ; x1 + = offx ; x0 + = offx ;
offy = - y0 ; y1 + = offy ; y0 + = offy ;
}
if ( ( x0 > = 0 ) & & ( y0 > = 0 ) & & ( x1 > x0 ) & & ( y1 > y0 ) )
{
2002-10-08 18:53:10 +08:00
* llx = ( int ) ( ( x0 / 72.0 ) * resolution + 0.0001 ) ;
* lly = ( int ) ( ( y0 / 72.0 ) * resolution + 0.0001 ) ;
2004-09-19 18:54:48 +08:00
/* Use upper bbox values as image size */
width = ( int ) ( ( x1 / 72.0 ) * resolution + 0.5 ) ;
height = ( int ) ( ( y1 / 72.0 ) * resolution + 0.5 ) ;
/* Pixel coordinates must be one less */
* urx = width - 1 ;
* ury = height - 1 ;
if ( * urx < * llx ) * urx = * llx ;
if ( * ury < * lly ) * ury = * lly ;
2000-03-26 06:19:17 +08:00
}
}
2000-01-26 01:46:56 +08:00
}
2004-01-26 07:46:24 +08:00
if ( loadopt - > pnm_type = = 4 )
driver = " pbmraw " ;
else if ( loadopt - > pnm_type = = 5 )
driver = " pgmraw " ;
else if ( loadopt - > pnm_type = = 7 )
driver = " pnmraw " ;
else
driver = " ppmraw " ;
1999-06-21 08:23:55 +08:00
# ifdef USE_REAL_OUTPUTFILE
2000-01-26 01:46:56 +08:00
/* For instance, the Win32 port of ghostscript doesn't work correctly when
* using standard output as output file .
* Thus , use a real output file .
*/
pnmfile = g_strdup_printf ( " %s " G_DIR_SEPARATOR_S " p%lx " ,
2004-01-26 07:46:24 +08:00
g_get_tmp_dir ( ) , ( gulong ) getpid ( ) ) ;
1999-06-21 08:23:55 +08:00
# else
2000-01-26 01:46:56 +08:00
pnmfile = " - " ;
1999-06-21 08:23:55 +08:00
# endif
1997-11-25 06:05:25 +08:00
2005-03-04 23:12:29 +08:00
gs = g_getenv ( " GS_PROG " ) ;
2000-02-08 06:53:28 +08:00
if ( gs = = NULL )
2003-03-22 09:12:48 +08:00
gs = DEFAULT_GS_PROG ;
2004-01-26 07:46:24 +08:00
/* Build command array */
cmdA = g_ptr_array_new ( ) ;
1997-11-25 06:05:25 +08:00
2004-01-26 07:46:24 +08:00
g_ptr_array_add ( cmdA , g_strdup ( gs ) ) ;
g_ptr_array_add ( cmdA , g_strdup_printf ( " -sDEVICE=%s " , driver ) ) ;
g_ptr_array_add ( cmdA , g_strdup_printf ( " -r%d " , resolution ) ) ;
2005-04-21 18:46:52 +08:00
if ( is_pdf )
{
/* Acrobat Reader honors CropBox over MediaBox, so let's match that
* behavior .
*/
g_ptr_array_add ( cmdA , g_strdup ( " -dUseCropBox " ) ) ;
}
else
{
/* For PDF, we can't set geometry */
g_ptr_array_add ( cmdA , g_strdup_printf ( " -g%dx%d " , width , height ) ) ;
}
2004-01-26 07:46:24 +08:00
/* Antialiasing not available for PBM-device */
if ( ( loadopt - > pnm_type ! = 4 ) & & ( loadopt - > textalpha ! = 1 ) )
g_ptr_array_add ( cmdA , g_strdup_printf ( " -dTextAlphaBits=%d " ,
loadopt - > textalpha ) ) ;
if ( ( loadopt - > pnm_type ! = 4 ) & & ( loadopt - > graphicsalpha ! = 1 ) )
g_ptr_array_add ( cmdA , g_strdup_printf ( " -dGraphicsAlphaBits=%d " ,
loadopt - > graphicsalpha ) ) ;
g_ptr_array_add ( cmdA , g_strdup ( " -q " ) ) ;
g_ptr_array_add ( cmdA , g_strdup ( " -dBATCH " ) ) ;
g_ptr_array_add ( cmdA , g_strdup ( " -dNOPAUSE " ) ) ;
/* If no additional options specified, use at least -dSAFER */
2005-03-04 23:12:29 +08:00
if ( g_getenv ( " GS_OPTIONS " ) = = NULL )
2004-01-26 07:46:24 +08:00
g_ptr_array_add ( cmdA , g_strdup ( " -dSAFER " ) ) ;
1997-11-25 06:05:25 +08:00
2004-01-26 07:46:24 +08:00
/* Output file name */
g_ptr_array_add ( cmdA , g_strdup_printf ( " -sOutputFile=%s " , pnmfile ) ) ;
2000-03-26 06:19:17 +08:00
/* Offset command for gs to get image part with negative x/y-coord. */
if ( ( offx ! = 0 ) | | ( offy ! = 0 ) )
2004-01-26 07:46:24 +08:00
{
g_ptr_array_add ( cmdA , g_strdup ( " -c " ) ) ;
g_ptr_array_add ( cmdA , g_strdup_printf ( " %d " , offx ) ) ;
g_ptr_array_add ( cmdA , g_strdup_printf ( " %d " , offy ) ) ;
g_ptr_array_add ( cmdA , g_strdup ( " translate " ) ) ;
}
1997-11-25 06:05:25 +08:00
2004-01-26 07:46:24 +08:00
/* input file name */
g_ptr_array_add ( cmdA , g_strdup ( " -f " ) ) ;
g_ptr_array_add ( cmdA , g_strdup ( filename ) ) ;
if ( * is_epsf )
{
g_ptr_array_add ( cmdA , g_strdup ( " -c " ) ) ;
g_ptr_array_add ( cmdA , g_strdup ( " showpage " ) ) ;
}
g_ptr_array_add ( cmdA , g_strdup ( " -c " ) ) ;
g_ptr_array_add ( cmdA , g_strdup ( " quit " ) ) ;
g_ptr_array_add ( cmdA , NULL ) ;
pcmdA = ( gchar * * ) cmdA - > pdata ;
1997-11-25 06:05:25 +08:00
# ifdef PS_DEBUG
2004-01-26 07:46:24 +08:00
{
gchar * * p = pcmdA ;
g_print ( " Starting command: \n " ) ;
while ( * p )
{
g_print ( " %s \n " , * p ) ;
p + + ;
}
}
1997-11-25 06:05:25 +08:00
# endif
1999-06-21 08:23:55 +08:00
2004-01-26 07:46:24 +08:00
/* Start the command */
1999-06-21 08:23:55 +08:00
# ifndef USE_REAL_OUTPUTFILE
2004-01-26 07:46:24 +08:00
Gflags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD ;
if ( ! g_spawn_async_with_pipes ( NULL , /* working dir */
pcmdA , /* command array */
NULL , /* environment */
Gflags , /* Flags */
NULL , NULL , /* Child setup and userdata */
ChildPidPtr ,
NULL , /* stdin */
& ChildStdout ,
NULL , /* stderr */
& Gerr ) )
{
2006-05-08 22:08:31 +08:00
g_message ( _ ( " Error starting Ghostscript. Make sure that Ghostscript is installed and - if necessary - use the environment variable GS_PROG to tell GIMP about its location. \n (%s) " ) , Gerr - > message ) ;
2004-01-26 07:46:24 +08:00
g_error_free ( Gerr ) ;
* ChildPidPtr = 0 ;
goto out ;
2000-01-26 01:46:56 +08:00
}
2004-10-06 21:18:37 +08:00
2004-01-26 07:46:24 +08:00
# ifdef PS_DEBUG
g_print ( " Ghostscript started with pid=%d \n " , * ChildPidPtr ) ;
2000-01-23 06:26:20 +08:00
# endif
2004-01-26 07:46:24 +08:00
/* Get a file pointer from the descriptor */
fd_popen = fdopen ( ChildStdout , " rb " ) ;
# else
/* Use a real outputfile. Wait until ghostscript has finished */
Gflags = G_SPAWN_SEARCH_PATH ;
if ( ! g_spawn_sync ( NULL , /* working dir */
pcmdA , /* command array */
NULL , /* environment */
Gflags , /* Flags */
NULL , NULL , /* Child setup and userdata */
NULL , /* stdout */
NULL , /* stderr */
NULL , /* exit code */
& Gerr ) )
{
2006-05-08 22:08:31 +08:00
g_message ( _ ( " Error starting Ghostscript. Make sure that Ghostscript is installed and - if necessary - use the environment variable GS_PROG to tell GIMP about its location. \n (%s) " ) , Gerr - > message ) ;
2004-01-26 07:46:24 +08:00
g_error_free ( Gerr ) ;
2005-03-04 23:12:29 +08:00
g_unlink ( pnmfile ) ;
2004-01-26 07:46:24 +08:00
goto out ;
}
/* Don't care about exit status of ghostscript. */
/* Just try to read what it wrote. */
2004-10-06 21:18:37 +08:00
2005-03-04 23:12:29 +08:00
fd_popen = g_fopen ( pnmfile , " rb " ) ;
2004-01-26 07:46:24 +08:00
1999-06-21 08:23:55 +08:00
# endif
1997-11-25 06:05:25 +08:00
2004-01-26 07:46:24 +08:00
out :
g_ptr_array_free ( cmdA , FALSE ) ;
g_strfreev ( pcmdA ) ;
return fd_popen ;
1997-11-25 06:05:25 +08:00
}
/* Close the PNM-File of the PostScript interpreter */
static void
2004-01-26 07:46:24 +08:00
ps_close ( FILE * ifp , gint ChildPid )
1997-11-25 06:05:25 +08:00
{
2004-11-19 05:10:12 +08:00
1999-06-21 08:23:55 +08:00
# ifndef USE_REAL_OUTPUTFILE
2004-01-26 07:46:24 +08:00
int status ;
pid_t RetVal ;
2000-08-21 07:26:11 +08:00
2004-11-19 21:34:07 +08:00
/* Enabling the code below causes us to read the pipe until EOF even
* if we dont want all images . Should be enabled if people report that
* the gs subprocess does not finish . For now it is disabled since it
* causes a significant slowdown .
*/
# ifdef EMPTY_PIPE
guchar buf [ 8192 ] ;
2004-01-26 07:46:24 +08:00
# ifdef PS_DEBUG
g_print ( " Reading rest from pipe \n " ) ;
# endif
2004-11-19 21:34:07 +08:00
while ( fread ( buf , sizeof ( buf ) , 1 , ifp ) ) ;
# endif /* EMPTY_PIPE */
2000-08-21 07:26:11 +08:00
2000-01-26 01:46:56 +08:00
/* Finish reading from pipe. */
2004-01-26 07:46:24 +08:00
fclose ( ifp ) ;
/* Wait for the child to exit */
if ( ChildPid )
{
# ifdef PS_DEBUG
g_print ( " Waiting for %d to finish \n " , ( int ) ChildPid ) ;
# endif
RetVal = waitpid ( ChildPid , & status , 0 ) ;
# ifdef PS_DEBUG
if ( RetVal = = - 1 )
g_print ( " waitpid() failed \n " ) ;
else
g_print ( " child has finished \n " ) ;
# endif
}
2004-11-19 21:34:07 +08:00
# else /* USE_REAL_OUTPUTFILE */
1999-06-21 08:23:55 +08:00
/* If a real outputfile was used, close the file and remove it. */
2000-01-26 01:46:56 +08:00
fclose ( ifp ) ;
2005-03-04 23:12:29 +08:00
g_unlink ( pnmfile ) ;
1999-06-21 08:23:55 +08:00
# endif
1997-11-25 06:05:25 +08:00
}
/* Read the header of a raw PNM-file and return type (4-6) or -1 on failure */
static gint
read_pnmraw_type ( FILE * ifp ,
2000-01-26 01:46:56 +08:00
gint * width ,
gint * height ,
gint * maxval )
{
register int frst , scnd , thrd ;
gint pnmtype ;
char line [ 1024 ] ;
/* GhostScript may write some informational messages infront of the header. */
/* We are just looking at a Px\n in the input stream. */
frst = getc ( ifp ) ;
scnd = getc ( ifp ) ;
thrd = getc ( ifp ) ;
for ( ; ; )
{
2004-11-19 05:10:12 +08:00
if ( thrd = = EOF ) return - 1 ;
2004-01-12 05:25:24 +08:00
# if defined (WIN32)
2000-01-26 01:46:56 +08:00
if ( thrd = = ' \r ' ) thrd = getc ( ifp ) ;
1999-05-02 00:10:36 +08:00
# endif
2000-01-26 01:46:56 +08:00
if ( ( thrd = = ' \n ' ) & & ( frst = = ' P ' ) & & ( scnd > = ' 1 ' ) & & ( scnd < = ' 6 ' ) )
2006-05-08 20:23:32 +08:00
break ;
2000-01-26 01:46:56 +08:00
frst = scnd ;
scnd = thrd ;
thrd = getc ( ifp ) ;
}
pnmtype = scnd - ' 0 ' ;
/* We dont use the ASCII-versions */
2004-11-19 05:10:12 +08:00
if ( ( pnmtype > = 1 ) & & ( pnmtype < = 3 ) )
return - 1 ;
2000-01-26 01:46:56 +08:00
/* Read width/height */
for ( ; ; )
{
2004-11-19 05:10:12 +08:00
if ( fgets ( line , sizeof ( line ) - 1 , ifp ) = = NULL )
return - 1 ;
if ( line [ 0 ] ! = ' # ' )
break ;
2000-01-26 01:46:56 +08:00
}
2004-11-19 05:10:12 +08:00
if ( sscanf ( line , " %d%d " , width , height ) ! = 2 )
return - 1 ;
2000-01-26 01:46:56 +08:00
* maxval = 255 ;
if ( pnmtype ! = 4 ) /* Read maxval */
{
for ( ; ; )
2006-05-08 20:23:32 +08:00
{
if ( fgets ( line , sizeof ( line ) - 1 , ifp ) = = NULL )
2004-11-19 05:10:12 +08:00
return - 1 ;
2006-05-08 20:23:32 +08:00
if ( line [ 0 ] ! = ' # ' )
2004-11-19 05:10:12 +08:00
break ;
2006-05-08 20:23:32 +08:00
}
2004-11-19 05:10:12 +08:00
if ( sscanf ( line , " %d " , maxval ) ! = 1 )
return - 1 ;
2000-01-26 01:46:56 +08:00
}
2004-11-19 05:10:12 +08:00
return pnmtype ;
1997-11-25 06:05:25 +08:00
}
/* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */
static gint32
2003-11-27 20:28:46 +08:00
create_new_image ( const gchar * filename ,
guint pagenum ,
guint width ,
guint height ,
2000-08-22 09:26:57 +08:00
GimpImageBaseType type ,
2003-11-27 20:28:46 +08:00
gint32 * layer_ID ,
GimpDrawable * * drawable ,
GimpPixelRgn * pixel_rgn )
2000-01-26 01:46:56 +08:00
{
2003-11-27 20:28:46 +08:00
gint32 image_ID ;
GimpImageType gdtype ;
2005-08-15 16:48:45 +08:00
gchar * tmp ;
2000-01-26 01:46:56 +08:00
2000-08-22 09:26:57 +08:00
if ( type = = GIMP_GRAY ) gdtype = GIMP_GRAY_IMAGE ;
else if ( type = = GIMP_INDEXED ) gdtype = GIMP_INDEXED_IMAGE ;
else gdtype = GIMP_RGB_IMAGE ;
2000-01-26 01:46:56 +08:00
image_ID = gimp_image_new ( width , height , type ) ;
2005-08-15 16:48:45 +08:00
gimp_image_undo_disable ( image_ID ) ;
2003-11-27 20:28:46 +08:00
2005-08-15 16:48:45 +08:00
tmp = g_strdup_printf ( " %s-%d " , filename , pagenum ) ;
gimp_image_set_filename ( image_ID , tmp ) ;
g_free ( tmp ) ;
2000-01-26 01:46:56 +08:00
2005-08-15 16:48:45 +08:00
tmp = g_strdup_printf ( _ ( " Page %d " ) , pagenum ) ;
* layer_ID = gimp_layer_new ( image_ID , tmp , width , height ,
2006-05-08 20:23:32 +08:00
gdtype , 100 , GIMP_NORMAL_MODE ) ;
2005-08-15 16:48:45 +08:00
g_free ( tmp ) ;
2000-01-26 01:46:56 +08:00
gimp_image_add_layer ( image_ID , * layer_ID , 0 ) ;
* drawable = gimp_drawable_get ( * layer_ID ) ;
gimp_pixel_rgn_init ( pixel_rgn , * drawable , 0 , 0 , ( * drawable ) - > width ,
2006-05-08 20:23:32 +08:00
( * drawable ) - > height , TRUE , FALSE ) ;
2000-01-26 01:46:56 +08:00
2003-11-27 20:28:46 +08:00
return image_ID ;
1997-11-25 06:05:25 +08:00
}
/* Skip PNM image generated from PostScript file. */
2004-11-19 05:10:12 +08:00
/* Return TRUE on success, FALSE otherwise. */
static gboolean
1997-11-25 06:05:25 +08:00
skip_ps ( FILE * ifp )
2000-01-26 01:46:56 +08:00
{
2004-11-19 05:10:12 +08:00
guchar buf [ 8192 ] ;
gsize len ;
gint pnmtype , width , height , maxval , bpl ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
pnmtype = read_pnmraw_type ( ifp , & width , & height , & maxval ) ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
if ( pnmtype = = 4 ) /* Portable bitmap */
2004-11-19 05:10:12 +08:00
bpl = ( width + 7 ) / 8 ;
2000-01-26 01:46:56 +08:00
else if ( pnmtype = = 5 )
bpl = width ;
else if ( pnmtype = = 6 )
2004-11-19 05:10:12 +08:00
bpl = width * 3 ;
2000-01-26 01:46:56 +08:00
else
2004-11-19 05:10:12 +08:00
return FALSE ;
1997-11-25 06:05:25 +08:00
2004-11-19 05:10:12 +08:00
len = bpl * height ;
while ( len )
2000-01-26 01:46:56 +08:00
{
2004-11-19 21:34:07 +08:00
gsize bytes = fread ( buf , 1 , MIN ( len , sizeof ( buf ) ) , ifp ) ;
1997-11-25 06:05:25 +08:00
2004-11-19 05:10:12 +08:00
if ( bytes < MIN ( len , sizeof ( buf ) ) )
return FALSE ;
len - = bytes ;
2000-01-26 01:46:56 +08:00
}
1997-11-25 06:05:25 +08:00
2004-11-19 05:10:12 +08:00
return TRUE ;
1997-11-25 06:05:25 +08:00
}
/* Load PNM image generated from PostScript file */
static gint32
2003-07-02 20:03:08 +08:00
load_ps ( const gchar * filename ,
guint pagenum ,
FILE * ifp ,
gint llx ,
gint lly ,
gint urx ,
gint ury )
2000-01-26 01:46:56 +08:00
{
register guchar * dest ;
guchar * data , * bitline = NULL , * byteline = NULL , * byteptr , * temp ;
guchar bit2byte [ 256 * 8 ] ;
int width , height , tile_height , scan_lines , total_scan_lines ;
int image_width , image_height ;
int skip_left , skip_bottom ;
int i , j , pnmtype , maxval , bpp , nread ;
2000-08-22 09:26:57 +08:00
GimpImageBaseType imagetype ;
2000-01-26 01:46:56 +08:00
gint32 layer_ID , image_ID ;
2000-08-22 09:26:57 +08:00
GimpPixelRgn pixel_rgn ;
GimpDrawable * drawable ;
2000-01-26 01:46:56 +08:00
int err = 0 , e ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
pnmtype = read_pnmraw_type ( ifp , & width , & height , & maxval ) ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
if ( ( width = = urx + 1 ) & & ( height = = ury + 1 ) ) /* gs respected BoundingBox ? */
{
skip_left = llx ; skip_bottom = lly ;
image_width = width - skip_left ;
image_height = height - skip_bottom ;
}
else
{
skip_left = skip_bottom = 0 ;
image_width = width ;
image_height = height ;
}
if ( pnmtype = = 4 ) /* Portable Bitmap */
{
2000-08-22 09:26:57 +08:00
imagetype = GIMP_INDEXED ;
2000-01-26 01:46:56 +08:00
nread = ( width + 7 ) / 8 ;
bpp = 1 ;
bitline = ( guchar * ) g_malloc ( nread ) ;
byteline = ( guchar * ) g_malloc ( nread * 8 ) ;
/* Get an array for mapping 8 bits in a byte to 8 bytes */
temp = bit2byte ;
for ( j = 0 ; j < 256 ; j + + )
2006-05-08 20:23:32 +08:00
for ( i = 7 ; i > = 0 ; i - - )
* ( temp + + ) = ( ( j & ( 1 < < i ) ) ! = 0 ) ;
2000-01-26 01:46:56 +08:00
}
else if ( pnmtype = = 5 ) /* Portable Greymap */
{
2000-08-22 09:26:57 +08:00
imagetype = GIMP_GRAY ;
2000-01-26 01:46:56 +08:00
nread = width ;
bpp = 1 ;
byteline = ( unsigned char * ) g_malloc ( nread ) ;
}
else if ( pnmtype = = 6 ) /* Portable Pixmap */
{
2000-08-22 09:26:57 +08:00
imagetype = GIMP_RGB ;
2000-01-26 01:46:56 +08:00
nread = width * 3 ;
bpp = 3 ;
byteline = ( guchar * ) g_malloc ( nread ) ;
}
2004-11-19 05:10:12 +08:00
else
return - 1 ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
image_ID = create_new_image ( filename , pagenum ,
2006-05-08 20:23:32 +08:00
image_width , image_height , imagetype ,
& layer_ID , & drawable , & pixel_rgn ) ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
tile_height = gimp_tile_height ( ) ;
data = g_malloc ( tile_height * image_width * bpp ) ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
dest = data ;
total_scan_lines = scan_lines = 0 ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
if ( pnmtype = = 4 ) /* Read bitimage ? Must be mapped to indexed */
{ static unsigned char BWColorMap [ 2 * 3 ] = { 255 , 255 , 255 , 0 , 0 , 0 } ;
1997-11-25 06:05:25 +08:00
2004-11-02 20:00:25 +08:00
gimp_image_set_colormap ( image_ID , BWColorMap , 2 ) ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
for ( i = 0 ; i < height ; i + + )
{
2006-05-08 20:23:32 +08:00
e = ( fread ( bitline , 1 , nread , ifp ) ! = nread ) ;
if ( total_scan_lines > = image_height ) continue ;
err | = e ;
if ( err ) break ;
j = width ; /* Map 1 byte of bitimage to 8 bytes of indexed image */
temp = bitline ;
byteptr = byteline ;
while ( j > = 8 )
{
memcpy ( byteptr , bit2byte + * ( temp + + ) * 8 , 8 ) ;
byteptr + = 8 ;
j - = 8 ;
}
if ( j > 0 )
memcpy ( byteptr , bit2byte + * temp * 8 , j ) ;
memcpy ( dest , byteline + skip_left , image_width ) ;
dest + = image_width ;
scan_lines + + ;
total_scan_lines + + ;
if ( ( i % 20 ) = = 0 )
gimp_progress_update ( ( double ) ( i + 1 ) / ( double ) image_height ) ;
if ( ( scan_lines = = tile_height ) | | ( ( i + 1 ) = = image_height ) )
{
gimp_pixel_rgn_set_rect ( & pixel_rgn , data , 0 , i - scan_lines + 1 ,
image_width , scan_lines ) ;
scan_lines = 0 ;
dest = data ;
}
if ( err ) break ;
2000-01-26 01:46:56 +08:00
}
}
else /* Read gray/rgb-image */
{
for ( i = 0 ; i < height ; i + + )
2006-05-08 20:23:32 +08:00
{
e = ( fread ( byteline , bpp , width , ifp ) ! = width ) ;
if ( total_scan_lines > = image_height ) continue ;
err | = e ;
if ( err ) break ;
memcpy ( dest , byteline + skip_left * bpp , image_width * bpp ) ;
dest + = image_width * bpp ;
scan_lines + + ;
total_scan_lines + + ;
if ( ( i % 20 ) = = 0 )
gimp_progress_update ( ( double ) ( i + 1 ) / ( double ) image_height ) ;
if ( ( scan_lines = = tile_height ) | | ( ( i + 1 ) = = image_height ) )
{
gimp_pixel_rgn_set_rect ( & pixel_rgn , data , 0 , i - scan_lines + 1 ,
image_width , scan_lines ) ;
scan_lines = 0 ;
dest = data ;
}
if ( err ) break ;
}
2000-01-26 01:46:56 +08:00
}
g_free ( data ) ;
if ( byteline ) g_free ( byteline ) ;
if ( bitline ) g_free ( bitline ) ;
if ( err )
g_message ( " EOF encountered on reading " ) ;
gimp_drawable_flush ( drawable ) ;
return ( err ? - 1 : image_ID ) ;
}
/* Write out the PostScript file header */
2003-07-02 20:03:08 +08:00
static void save_ps_header ( FILE * ofp ,
const gchar * filename )
2000-01-26 01:46:56 +08:00
{
2004-08-09 06:26:17 +08:00
gchar * basename = g_path_get_basename ( filename ) ;
time_t cutime = time ( NULL ) ;
2000-01-26 01:46:56 +08:00
fprintf ( ofp , " %%!PS-Adobe-3.0%s \n " , psvals . eps ? " EPSF-3.0 " : " " ) ;
fprintf ( ofp , " %%%%Creator: GIMP PostScript file plugin V %4.2f \
by Peter Kirchgessner \ n " , VERSIO);
2004-08-09 06:26:17 +08:00
fprintf ( ofp , " %%%%Title: %s \n " , basename ) ;
2000-01-26 01:46:56 +08:00
fprintf ( ofp , " %%%%CreationDate: %s " , ctime ( & cutime ) ) ;
fprintf ( ofp , " %%%%DocumentData: Clean7Bit \n " ) ;
if ( psvals . eps | | ( psvals . level > 1 ) ) fprintf ( ofp , " %%%%LanguageLevel: 2 \n " ) ;
fprintf ( ofp , " %%%%Pages: 1 \n " ) ;
2004-08-09 06:26:17 +08:00
g_free ( basename ) ;
2000-01-26 01:46:56 +08:00
}
/* Write out transformation for image */
static void
save_ps_setup ( FILE * ofp ,
gint32 drawable_ID ,
gint width ,
gint height ,
gint bpp )
{
double x_offset , y_offset , x_size , y_size ;
2002-10-08 18:53:10 +08:00
double urx , ury ;
2000-01-26 01:46:56 +08:00
double x_scale , y_scale ;
double width_inch , height_inch ;
double f1 , f2 , dx , dy ;
int xtrans , ytrans ;
2002-10-08 18:53:10 +08:00
int i_urx , i_ury ;
2002-12-17 03:24:05 +08:00
char tmpbuf [ G_ASCII_DTOSTR_BUF_SIZE ] ;
2000-01-26 01:46:56 +08:00
/* initialize */
dx = 0.0 ;
dy = 0.0 ;
1997-11-25 06:05:25 +08:00
x_offset = psvals . x_offset ;
y_offset = psvals . y_offset ;
width_inch = fabs ( psvals . width ) ;
height_inch = fabs ( psvals . height ) ;
if ( psvals . unit_mm )
2000-01-26 01:46:56 +08:00
{
x_offset / = 25.4 ; y_offset / = 25.4 ;
width_inch / = 25.4 ; height_inch / = 25.4 ;
}
1997-11-25 06:05:25 +08:00
if ( psvals . keep_ratio ) /* Proportions to keep ? */
2000-01-26 01:46:56 +08:00
{ /* Fit the image into the allowed size */
f1 = width_inch / width ;
f2 = height_inch / height ;
if ( f1 < f2 )
2006-05-08 20:23:32 +08:00
height_inch = width_inch * ( double ) ( height ) / ( double ) ( width ) ;
2000-01-26 01:46:56 +08:00
else
2006-05-08 20:23:32 +08:00
width_inch = fabs ( height_inch ) * ( double ) ( width ) / ( double ) ( height ) ;
2000-01-26 01:46:56 +08:00
}
1997-11-25 06:05:25 +08:00
if ( ( psvals . rotate = = 0 ) | | ( psvals . rotate = = 180 ) )
2000-01-26 01:46:56 +08:00
{
x_size = width_inch ; y_size = height_inch ;
}
1997-11-25 06:05:25 +08:00
else
2000-01-26 01:46:56 +08:00
{
y_size = width_inch ; x_size = height_inch ;
}
1997-11-25 06:05:25 +08:00
2002-10-08 18:53:10 +08:00
/* Round up upper right corner only for non-integer values */
urx = ( x_offset + x_size ) * 72.0 ;
ury = ( y_offset + y_size ) * 72.0 ;
i_urx = ( int ) urx ;
i_ury = ( int ) ury ;
if ( urx ! = ( double ) i_urx ) i_urx + + ; /* Check for non-integer value */
if ( ury ! = ( double ) i_ury ) i_ury + + ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " %%%%BoundingBox: %d %d %d %d \n " , ( int ) ( x_offset * 72.0 ) ,
2002-10-08 18:53:10 +08:00
( int ) ( y_offset * 72.0 ) , i_urx , i_ury ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " %%%%EndComments \n " ) ;
1997-12-26 15:08:20 +08:00
if ( psvals . preview & & ( psvals . preview_size > 0 ) )
2000-01-26 01:46:56 +08:00
{
save_ps_preview ( ofp , drawable_ID ) ;
}
1997-12-26 15:08:20 +08:00
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " %%%%BeginProlog \n " ) ;
fprintf ( ofp , " %% Use own dictionary to avoid conflicts \n " ) ;
2000-03-11 01:27:25 +08:00
fprintf ( ofp , " 10 dict begin \n " ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " %%%%EndProlog \n " ) ;
fprintf ( ofp , " %%%%Page: 1 1 \n " ) ;
fprintf ( ofp , " %% Translate for offset \n " ) ;
2002-12-17 03:24:05 +08:00
fprintf ( ofp , " %s " , g_ascii_dtostr ( tmpbuf , sizeof ( tmpbuf ) , x_offset * 72.0 ) ) ;
fprintf ( ofp , " %s translate \n " , g_ascii_dtostr ( tmpbuf , sizeof ( tmpbuf ) , y_offset * 72.0 ) ) ;
1997-11-25 06:05:25 +08:00
/* Calculate translation to startpoint of first scanline */
switch ( psvals . rotate )
2000-01-26 01:46:56 +08:00
{
1997-11-25 06:05:25 +08:00
case 0 : dx = 0.0 ; dy = y_size * 72.0 ;
2000-01-26 01:46:56 +08:00
break ;
1997-11-25 06:05:25 +08:00
case 90 : dx = dy = 0.0 ;
2000-01-26 01:46:56 +08:00
x_scale = 72.0 * width_inch ;
y_scale = - 72.0 * height_inch ;
break ;
case 180 : dx = x_size * 72.0 ; dy = 0.0 ;
break ;
case 270 : dx = x_size * 72.0 ; dy = y_size * 72.0 ;
break ;
}
1997-11-25 06:05:25 +08:00
if ( ( dx ! = 0.0 ) | | ( dy ! = 0.0 ) )
2002-12-17 03:24:05 +08:00
{
fprintf ( ofp , " %% Translate to begin of first scanline \n " ) ;
fprintf ( ofp , " %s " , g_ascii_dtostr ( tmpbuf , sizeof ( tmpbuf ) , dx ) ) ;
fprintf ( ofp , " %s translate \n " , g_ascii_dtostr ( tmpbuf , sizeof ( tmpbuf ) , dy ) ) ;
}
1997-11-25 06:05:25 +08:00
if ( psvals . rotate )
fprintf ( ofp , " %d rotate \n " , ( int ) psvals . rotate ) ;
2002-12-17 03:24:05 +08:00
fprintf ( ofp , " %s " , g_ascii_dtostr ( tmpbuf , sizeof ( tmpbuf ) , 72.0 * width_inch ) ) ;
fprintf ( ofp , " %s scale \n " , g_ascii_dtostr ( tmpbuf , sizeof ( tmpbuf ) , - 72.0 * height_inch ) ) ;
1997-11-25 06:05:25 +08:00
/* Write the PostScript procedures to read the image */
2000-01-23 06:26:20 +08:00
if ( psvals . level < = 1 )
{
fprintf ( ofp , " %% Variable to keep one line of raster data \n " ) ;
if ( bpp = = 1 )
fprintf ( ofp , " /scanline %d string def \n " , ( width + 7 ) / 8 ) ;
else
fprintf ( ofp , " /scanline %d %d mul string def \n " , width , bpp / 8 ) ;
}
1999-01-04 06:41:12 +08:00
fprintf ( ofp , " %% Image geometry \n %d %d %d \n " , width , height ,
( bpp = = 1 ) ? 1 : 8 ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " %% Transformation matrix \n " ) ;
xtrans = ytrans = 0 ;
if ( psvals . width < 0.0 ) { width = - width ; xtrans = - width ; }
if ( psvals . height < 0.0 ) { height = - height ; ytrans = - height ; }
fprintf ( ofp , " [ %d 0 0 %d %d %d ] \n " , width , height , xtrans , ytrans ) ;
}
1997-12-26 15:08:20 +08:00
static void
save_ps_trailer ( FILE * ofp )
1997-11-25 06:05:25 +08:00
{
1997-12-26 15:08:20 +08:00
fprintf ( ofp , " %%%%Trailer \n " ) ;
fprintf ( ofp , " end \n %%%%EOF \n " ) ;
1997-11-25 06:05:25 +08:00
}
1997-12-26 15:08:20 +08:00
/* Do a Floyd-Steinberg dithering on a greyscale scanline. */
/* linecount must keep the counter for the actual scanline (0, 1, 2, ...). */
/* If linecount is less than zero, all used memory is freed. */
static void
2006-08-29 21:32:22 +08:00
dither_grey ( const guchar * grey ,
guchar * bw ,
gint npix ,
gint linecount )
2000-01-26 01:46:56 +08:00
{
2006-08-29 21:32:22 +08:00
static gboolean do_init_arrays = TRUE ;
static gint * fs_error = NULL ;
static gint limit [ 1278 ] ;
static gint east_error [ 256 ] ;
static gint seast_error [ 256 ] ;
static gint south_error [ 256 ] ;
static gint swest_error [ 256 ] ;
register const guchar * greyptr ;
register guchar * bwptr , mask ;
register gint * fse ;
gint x , greyval , fse_inline ;
2000-01-26 01:46:56 +08:00
if ( linecount < = 0 )
{
2006-08-29 21:32:22 +08:00
g_free ( fs_error ) ;
if ( linecount < 0 )
return ;
fs_error = g_new0 ( gint , npix + 2 ) ;
2000-01-26 01:46:56 +08:00
/* Initialize some arrays that speed up dithering */
if ( do_init_arrays )
2006-05-08 20:23:32 +08:00
{
2006-08-29 21:32:22 +08:00
gint i ;
do_init_arrays = FALSE ;
for ( i = 0 , x = - 511 ; x < = 766 ; i + + , x + + )
limit [ i ] = ( x < 0 ) ? 0 : ( ( x > 255 ) ? 255 : x ) ;
2006-05-08 20:23:32 +08:00
for ( greyval = 0 ; greyval < 256 ; greyval + + )
{
2006-08-29 21:32:22 +08:00
east_error [ greyval ] = ( greyval < 128 ) ?
( ( greyval * 79 ) > > 8 ) : ( ( ( greyval - 255 ) * 79 ) > > 8 ) ;
seast_error [ greyval ] = ( greyval < 128 ) ?
( ( greyval * 34 ) > > 8 ) : ( ( ( greyval - 255 ) * 34 ) > > 8 ) ;
south_error [ greyval ] = ( greyval < 128 ) ?
( ( greyval * 56 ) > > 8 ) : ( ( ( greyval - 255 ) * 56 ) > > 8 ) ;
swest_error [ greyval ] = ( greyval < 128 ) ?
( ( greyval * 12 ) > > 8 ) : ( ( ( greyval - 255 ) * 12 ) > > 8 ) ;
2006-05-08 20:23:32 +08:00
}
}
2000-01-26 01:46:56 +08:00
}
2006-08-29 21:32:22 +08:00
g_return_if_fail ( fs_error ! = NULL ) ;
memset ( bw , 0 , ( npix + 7 ) / 8 ) ; /* Initialize with white */
2000-01-26 01:46:56 +08:00
greyptr = grey ;
bwptr = bw ;
mask = 0x80 ;
2006-08-29 21:32:22 +08:00
fse_inline = fs_error [ 1 ] ;
for ( x = 0 , fse = fs_error + 1 ; x < npix ; x + + , fse + + )
2000-01-26 01:46:56 +08:00
{
2006-08-29 21:32:22 +08:00
greyval =
limit [ * ( greyptr + + ) + fse_inline + 512 ] ; /* 0 <= greyval <= 255 */
if ( greyval < 128 )
* bwptr | = mask ; /* Set a black pixel */
2000-01-26 01:46:56 +08:00
/* Error distribution */
fse_inline = east_error [ greyval ] + fse [ 1 ] ;
fse [ 1 ] = seast_error [ greyval ] ;
fse [ 0 ] + = south_error [ greyval ] ;
fse [ - 1 ] + = swest_error [ greyval ] ;
mask > > = 1 ; /* Get mask for next b/w-pixel */
2006-08-29 21:32:22 +08:00
2000-01-26 01:46:56 +08:00
if ( ! mask )
2006-05-08 20:23:32 +08:00
{
mask = 0x80 ;
bwptr + + ;
}
2000-01-26 01:46:56 +08:00
}
1997-12-26 15:08:20 +08:00
}
/* Write a device independant screen preview */
static void
2000-01-26 01:46:56 +08:00
save_ps_preview ( FILE * ofp ,
gint32 drawable_ID )
{
register guchar * bwptr , * greyptr ;
2000-08-22 09:26:57 +08:00
GimpImageType drawable_type ;
GimpDrawable * drawable ;
GimpPixelRgn src_rgn ;
2000-01-26 01:46:56 +08:00
int width , height , x , y , nbsl , out_count ;
int nchar_pl = 72 , src_y ;
double f1 , f2 ;
guchar * grey , * bw , * src_row , * src_ptr ;
guchar * cmap ;
gint ncols , cind ;
if ( psvals . preview_size < = 0 ) return ;
drawable = gimp_drawable_get ( drawable_ID ) ;
drawable_type = gimp_drawable_type ( drawable_ID ) ;
/* Calculate size of preview */
if ( ( drawable - > width < = psvals . preview_size )
2006-05-08 20:23:32 +08:00
& & ( drawable - > height < = psvals . preview_size ) )
2000-01-26 01:46:56 +08:00
{
width = drawable - > width ;
height = drawable - > height ;
}
else
{
f1 = ( double ) psvals . preview_size / ( double ) drawable - > width ;
f2 = ( double ) psvals . preview_size / ( double ) drawable - > height ;
if ( f1 < f2 )
2006-05-08 20:23:32 +08:00
{
width = psvals . preview_size ;
height = drawable - > height * f1 ;
if ( height < = 0 ) height = 1 ;
}
2000-01-26 01:46:56 +08:00
else
2006-05-08 20:23:32 +08:00
{
height = psvals . preview_size ;
width = drawable - > width * f1 ;
if ( width < = 0 ) width = 1 ;
}
2000-01-26 01:46:56 +08:00
}
nbsl = ( width + 7 ) / 8 ; /* Number of bytes per scanline in bitmap */
grey = ( guchar * ) g_malloc ( width ) ;
bw = ( guchar * ) g_malloc ( nbsl ) ;
src_row = ( guchar * ) g_malloc ( drawable - > width * drawable - > bpp ) ;
fprintf ( ofp , " %%%%BeginPreview: %d %d 1 %d \n " , width , height ,
2006-05-08 20:23:32 +08:00
( ( nbsl * 2 + nchar_pl - 1 ) / nchar_pl ) * height ) ;
2000-01-26 01:46:56 +08:00
gimp_pixel_rgn_init ( & src_rgn , drawable , 0 , 0 , drawable - > width ,
2006-05-08 20:23:32 +08:00
drawable - > height , FALSE , FALSE ) ;
2000-01-26 01:46:56 +08:00
cmap = NULL ; /* Check if we need a colour table */
2000-08-22 09:26:57 +08:00
if ( gimp_drawable_type ( drawable_ID ) = = GIMP_INDEXED_IMAGE )
2000-01-26 01:46:56 +08:00
cmap = ( guchar * )
2004-11-02 20:00:25 +08:00
gimp_image_get_colormap ( gimp_drawable_get_image ( drawable_ID ) , & ncols ) ;
2000-01-26 01:46:56 +08:00
for ( y = 0 ; y < height ; y + + )
{
/* Get a scanline from the input image and scale it to the desired width */
src_y = ( y * drawable - > height ) / height ;
gimp_pixel_rgn_get_row ( & src_rgn , src_row , 0 , src_y , drawable - > width ) ;
greyptr = grey ;
if ( drawable - > bpp = = 3 ) /* RGB-image */
2006-05-08 20:23:32 +08:00
{
for ( x = 0 ; x < width ; x + + )
{ /* Convert to grey */
src_ptr = src_row + ( ( x * drawable - > width ) / width ) * 3 ;
* ( greyptr + + ) = ( 3 * src_ptr [ 0 ] + 6 * src_ptr [ 1 ] + src_ptr [ 2 ] ) / 10 ;
}
}
2000-01-26 01:46:56 +08:00
else if ( cmap ) /* Indexed image */
2006-05-08 20:23:32 +08:00
{
for ( x = 0 ; x < width ; x + + )
{
src_ptr = src_row + ( ( x * drawable - > width ) / width ) ;
cind = * src_ptr ; /* Get colour index and convert to grey */
src_ptr = ( cind > = ncols ) ? cmap : ( cmap + 3 * cind ) ;
* ( greyptr + + ) = ( 3 * src_ptr [ 0 ] + 6 * src_ptr [ 1 ] + src_ptr [ 2 ] ) / 10 ;
}
}
2000-01-26 01:46:56 +08:00
else /* Grey image */
2006-05-08 20:23:32 +08:00
{
for ( x = 0 ; x < width ; x + + )
* ( greyptr + + ) = * ( src_row + ( ( x * drawable - > width ) / width ) ) ;
}
2000-01-26 01:46:56 +08:00
/* Now we have a greyscale line for the desired width. */
/* Dither it to b/w */
dither_grey ( grey , bw , width , y ) ;
/* Write out the b/w line */
out_count = 0 ;
bwptr = bw ;
for ( x = 0 ; x < nbsl ; x + + )
2006-05-08 20:23:32 +08:00
{
if ( out_count = = 0 ) fprintf ( ofp , " %% " ) ;
fprintf ( ofp , " %02x " , * ( bwptr + + ) ) ;
out_count + = 2 ;
if ( out_count > = nchar_pl )
{
fprintf ( ofp , " \n " ) ;
out_count = 0 ;
}
}
2000-01-26 01:46:56 +08:00
if ( out_count ! = 0 )
2006-05-08 20:23:32 +08:00
fprintf ( ofp , " \n " ) ;
2000-01-26 01:46:56 +08:00
2003-06-13 22:37:00 +08:00
if ( ( y % 20 ) = = 0 )
2006-05-08 20:23:32 +08:00
gimp_progress_update ( ( double ) ( y ) / ( double ) height ) ;
2000-01-26 01:46:56 +08:00
}
fprintf ( ofp , " %%%%EndPreview \n " ) ;
dither_grey ( grey , bw , width , - 1 ) ;
g_free ( src_row ) ;
g_free ( bw ) ;
g_free ( grey ) ;
gimp_drawable_detach ( drawable ) ;
1997-12-26 15:08:20 +08:00
}
1997-11-25 06:05:25 +08:00
static gint
2000-01-26 01:46:56 +08:00
save_gray ( FILE * ofp ,
gint32 image_ID ,
gint32 drawable_ID )
{
int height , width , i , j ;
1997-11-25 06:05:25 +08:00
int tile_height ;
unsigned char * data , * src ;
2000-03-11 01:27:25 +08:00
unsigned char * packb = NULL ;
2000-08-22 09:26:57 +08:00
GimpPixelRgn pixel_rgn ;
GimpDrawable * drawable ;
GimpImageType drawable_type ;
1997-11-25 06:05:25 +08:00
static char * hex = " 0123456789abcdef " ;
2000-01-23 06:26:20 +08:00
int level2 = ( psvals . level > 1 ) ;
1997-11-25 06:05:25 +08:00
drawable = gimp_drawable_get ( drawable_ID ) ;
drawable_type = gimp_drawable_type ( drawable_ID ) ;
width = drawable - > width ;
height = drawable - > height ;
tile_height = gimp_tile_height ( ) ;
gimp_pixel_rgn_init ( & pixel_rgn , drawable , 0 , 0 , width , height , FALSE , FALSE ) ;
/* allocate a buffer for retrieving information from the pixel region */
2000-01-26 01:46:56 +08:00
src = data = ( guchar * ) g_malloc ( tile_height * width * drawable - > bpp ) ;
1997-11-25 06:05:25 +08:00
/* Set up transformation in PostScript */
1999-01-04 06:41:12 +08:00
save_ps_setup ( ofp , drawable_ID , width , height , 1 * 8 ) ;
1997-11-25 06:05:25 +08:00
/* Write read image procedure */
2000-01-23 06:26:20 +08:00
if ( ! level2 )
{
fprintf ( ofp , " { currentfile scanline readhexstring pop } \n " ) ;
}
else
{
2000-03-11 01:27:25 +08:00
fprintf ( ofp , " currentfile /ASCII85Decode filter /RunLengthDecode filter \n " ) ;
2000-01-23 06:26:20 +08:00
ascii85_init ( ) ;
2000-03-11 01:27:25 +08:00
/* Allocate buffer for packbits data. Worst case: Less than 1% increase */
packb = ( guchar * ) g_malloc ( ( width * 105 ) / 100 + 2 ) ;
2000-01-23 06:26:20 +08:00
}
2000-04-05 18:26:08 +08:00
ps_begin_data ( ofp ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " image \n " ) ;
# define GET_GRAY_TILE(begin) \
{ int scan_lines ; \
scan_lines = ( i + tile_height - 1 < height ) ? tile_height : ( height - i ) ; \
gimp_pixel_rgn_get_rect ( & pixel_rgn , begin , 0 , i , width , scan_lines ) ; \
src = begin ; }
for ( i = 0 ; i < height ; i + + )
{
2000-01-26 01:46:56 +08:00
if ( ( i % tile_height ) = = 0 ) GET_GRAY_TILE ( data ) ; /* Get more data */
if ( ! level2 )
2006-05-08 20:23:32 +08:00
{
for ( j = 0 ; j < width ; j + + )
{
putc ( hex [ ( * src ) > > 4 ] , ofp ) ;
putc ( hex [ ( * ( src + + ) ) & 0x0f ] , ofp ) ;
if ( ( ( j + 1 ) % 39 ) = = 0 ) putc ( ' \n ' , ofp ) ;
}
putc ( ' \n ' , ofp ) ;
}
2000-01-26 01:46:56 +08:00
else
2006-05-08 20:23:32 +08:00
{ int nout ;
2000-03-11 01:27:25 +08:00
compress_packbits ( width , src , & nout , packb ) ;
ascii85_nout ( nout , packb , ofp ) ;
src + = width ;
2006-05-08 20:23:32 +08:00
}
2003-06-13 22:37:00 +08:00
if ( ( i % 20 ) = = 0 )
2006-05-08 20:23:32 +08:00
gimp_progress_update ( ( double ) i / ( double ) height ) ;
1997-11-25 06:05:25 +08:00
}
2003-06-13 22:37:00 +08:00
2000-03-11 01:27:25 +08:00
if ( level2 )
2003-06-13 22:37:00 +08:00
{
ascii85_out ( 128 , ofp ) ; /* Write EOD of RunLengthDecode filter */
ascii85_done ( ofp ) ;
}
2000-04-05 18:26:08 +08:00
ps_end_data ( ofp ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " showpage \n " ) ;
g_free ( data ) ;
2003-06-13 22:37:00 +08:00
if ( packb )
g_free ( packb ) ;
1997-11-25 06:05:25 +08:00
gimp_drawable_detach ( drawable ) ;
if ( ferror ( ofp ) )
2000-01-26 01:46:56 +08:00
{
2004-05-24 05:12:29 +08:00
g_message ( _ ( " Write error occurred " ) ) ;
2004-11-19 05:10:12 +08:00
return FALSE ;
2000-01-26 01:46:56 +08:00
}
2004-11-19 05:10:12 +08:00
return TRUE ;
1997-11-25 06:05:25 +08:00
# undef GET_GRAY_TILE
}
static gint
2000-01-26 01:46:56 +08:00
save_bw ( FILE * ofp ,
gint32 image_ID ,
gint32 drawable_ID )
{
int height , width , i , j ;
1999-01-04 06:41:12 +08:00
int ncols , nbsl , nwrite ;
1997-11-25 06:05:25 +08:00
int tile_height ;
2000-01-26 01:46:56 +08:00
guchar * cmap , * ct ;
guchar * data , * src ;
2000-03-11 01:27:25 +08:00
guchar * packb = NULL ;
2000-01-26 01:46:56 +08:00
guchar * scanline , * dst , mask ;
guchar * hex_scanline ;
2000-08-22 09:26:57 +08:00
GimpPixelRgn pixel_rgn ;
GimpDrawable * drawable ;
GimpImageType drawable_type ;
1997-11-25 06:05:25 +08:00
static char * hex = " 0123456789abcdef " ;
2003-07-03 21:26:06 +08:00
gint level2 = ( psvals . level > 1 ) ;
1999-01-04 06:41:12 +08:00
2004-11-02 20:00:25 +08:00
cmap = gimp_image_get_colormap ( image_ID , & ncols ) ;
1997-11-25 06:05:25 +08:00
drawable = gimp_drawable_get ( drawable_ID ) ;
drawable_type = gimp_drawable_type ( drawable_ID ) ;
width = drawable - > width ;
height = drawable - > height ;
tile_height = gimp_tile_height ( ) ;
2003-07-03 21:26:06 +08:00
gimp_pixel_rgn_init ( & pixel_rgn ,
drawable , 0 , 0 , width , height , FALSE , FALSE ) ;
1997-11-25 06:05:25 +08:00
/* allocate a buffer for retrieving information from the pixel region */
2003-07-03 21:26:06 +08:00
src = data = g_new ( guchar , tile_height * width * drawable - > bpp ) ;
1999-01-04 06:41:12 +08:00
nbsl = ( width + 7 ) / 8 ;
2003-07-03 21:26:06 +08:00
scanline = g_new ( guchar , nbsl + 1 ) ;
hex_scanline = g_new ( guchar , ( nbsl + 1 ) * 2 ) ;
1999-01-04 06:41:12 +08:00
/* Set up transformation in PostScript */
save_ps_setup ( ofp , drawable_ID , width , height , 1 ) ;
/* Write read image procedure */
2000-01-23 06:26:20 +08:00
if ( ! level2 )
{
fprintf ( ofp , " { currentfile scanline readhexstring pop } \n " ) ;
}
else
{
2000-03-11 01:27:25 +08:00
fprintf ( ofp , " currentfile /ASCII85Decode filter /RunLengthDecode filter \n " ) ;
2000-01-23 06:26:20 +08:00
ascii85_init ( ) ;
2000-03-11 01:27:25 +08:00
/* Allocate buffer for packbits data. Worst case: Less than 1% increase */
2003-07-03 21:26:06 +08:00
packb = g_new ( guchar , ( ( nbsl + 1 ) * 105 ) / 100 + 2 ) ;
2000-01-23 06:26:20 +08:00
}
2000-04-05 18:26:08 +08:00
ps_begin_data ( ofp ) ;
1999-01-04 06:41:12 +08:00
fprintf ( ofp , " image \n " ) ;
# define GET_BW_TILE(begin) \
{ int scan_lines ; \
scan_lines = ( i + tile_height - 1 < height ) ? tile_height : ( height - i ) ; \
gimp_pixel_rgn_get_rect ( & pixel_rgn , begin , 0 , i , width , scan_lines ) ; \
src = begin ; }
for ( i = 0 ; i < height ; i + + )
{
2000-01-26 01:46:56 +08:00
if ( ( i % tile_height ) = = 0 ) GET_BW_TILE ( data ) ; /* Get more data */
2000-01-23 06:26:20 +08:00
dst = scanline ;
2000-01-26 01:46:56 +08:00
memset ( dst , 0 , nbsl ) ;
mask = 0x80 ;
/* Build a bitmap for a scanline */
for ( j = 0 ; j < width ; j + + )
2006-05-08 20:23:32 +08:00
{
ct = cmap + * ( src + + ) * 3 ;
if ( ct [ 0 ] | | ct [ 1 ] | | ct [ 2 ] )
* dst | = mask ;
if ( mask = = 0x01 ) { mask = 0x80 ; dst + + ; } else mask > > = 1 ;
}
2000-01-26 01:46:56 +08:00
if ( ! level2 )
2006-05-08 20:23:32 +08:00
{
/* Convert to hexstring */
for ( j = 0 ; j < nbsl ; j + + )
{
hex_scanline [ j * 2 ] = ( unsigned char ) hex [ scanline [ j ] > > 4 ] ;
hex_scanline [ j * 2 + 1 ] = ( unsigned char ) hex [ scanline [ j ] & 0x0f ] ;
}
/* Write out hexstring */
j = nbsl * 2 ;
dst = hex_scanline ;
while ( j > 0 )
{
nwrite = ( j > 78 ) ? 78 : j ;
fwrite ( dst , nwrite , 1 , ofp ) ;
putc ( ' \n ' , ofp ) ;
j - = nwrite ;
dst + = nwrite ;
}
}
2000-01-26 01:46:56 +08:00
else
2006-05-08 20:23:32 +08:00
{ int nout ;
2000-03-11 01:27:25 +08:00
compress_packbits ( nbsl , scanline , & nout , packb ) ;
ascii85_nout ( nout , packb , ofp ) ;
2006-05-08 20:23:32 +08:00
}
2003-06-13 22:37:00 +08:00
if ( ( i % 20 ) = = 0 )
2006-05-08 20:23:32 +08:00
gimp_progress_update ( ( double ) i / ( double ) height ) ;
1999-01-04 06:41:12 +08:00
}
2003-06-13 22:37:00 +08:00
2000-03-11 01:27:25 +08:00
if ( level2 )
2003-06-13 22:37:00 +08:00
{
ascii85_out ( 128 , ofp ) ; /* Write EOD of RunLengthDecode filter */
ascii85_done ( ofp ) ;
}
2000-04-05 18:26:08 +08:00
ps_end_data ( ofp ) ;
1999-01-04 06:41:12 +08:00
fprintf ( ofp , " showpage \n " ) ;
g_free ( hex_scanline ) ;
g_free ( scanline ) ;
g_free ( data ) ;
2003-06-13 22:37:00 +08:00
if ( packb )
g_free ( packb ) ;
1999-01-04 06:41:12 +08:00
gimp_drawable_detach ( drawable ) ;
if ( ferror ( ofp ) )
2000-01-26 01:46:56 +08:00
{
2004-05-24 05:12:29 +08:00
g_message ( _ ( " Write error occurred " ) ) ;
2004-11-19 05:10:12 +08:00
return FALSE ;
2000-01-26 01:46:56 +08:00
}
2004-11-19 05:10:12 +08:00
return TRUE ;
1999-01-04 06:41:12 +08:00
# undef GET_BW_TILE
}
static gint
2000-01-26 01:46:56 +08:00
save_index ( FILE * ofp ,
gint32 image_ID ,
gint32 drawable_ID )
{
int height , width , i , j ;
1999-01-04 06:41:12 +08:00
int ncols , bw ;
int tile_height ;
2000-03-11 01:27:25 +08:00
guchar * cmap , * cmap_start ;
guchar * data , * src ;
guchar * packb = NULL , * plane = NULL ;
1999-01-04 06:41:12 +08:00
char coltab [ 256 * 6 ] , * ct ;
2000-08-22 09:26:57 +08:00
GimpPixelRgn pixel_rgn ;
GimpDrawable * drawable ;
GimpImageType drawable_type ;
1999-01-04 06:41:12 +08:00
static char * hex = " 0123456789abcdef " ;
static char * background = " 000000 " ;
2000-01-23 06:26:20 +08:00
int level2 = ( psvals . level > 1 ) ;
1997-11-25 06:05:25 +08:00
2004-11-02 20:00:25 +08:00
cmap = cmap_start = gimp_image_get_colormap ( image_ID , & ncols ) ;
1997-11-25 06:05:25 +08:00
ct = coltab ;
1999-01-04 06:41:12 +08:00
bw = 1 ;
1997-11-25 06:05:25 +08:00
for ( j = 0 ; j < 256 ; j + + )
{
2000-01-26 01:46:56 +08:00
if ( j > = ncols )
2006-05-08 20:23:32 +08:00
{
memcpy ( ct , background , 6 ) ;
ct + = 6 ;
}
2000-01-26 01:46:56 +08:00
else
2006-05-08 20:23:32 +08:00
{
bw & = ( ( cmap [ 0 ] = = 0 ) & & ( cmap [ 1 ] = = 0 ) & & ( cmap [ 2 ] = = 0 ) )
1999-01-04 06:41:12 +08:00
| | ( ( cmap [ 0 ] = = 255 ) & & ( cmap [ 1 ] = = 255 ) & & ( cmap [ 2 ] = = 255 ) ) ;
2006-05-08 20:23:32 +08:00
* ( ct + + ) = ( guchar ) hex [ ( * cmap ) > > 4 ] ;
* ( ct + + ) = ( guchar ) hex [ ( * ( cmap + + ) ) & 0x0f ] ;
* ( ct + + ) = ( guchar ) hex [ ( * cmap ) > > 4 ] ;
* ( ct + + ) = ( guchar ) hex [ ( * ( cmap + + ) ) & 0x0f ] ;
* ( ct + + ) = ( guchar ) hex [ ( * cmap ) > > 4 ] ;
* ( ct + + ) = ( guchar ) hex [ ( * ( cmap + + ) ) & 0x0f ] ;
}
1997-11-25 06:05:25 +08:00
}
2004-11-19 05:10:12 +08:00
if ( bw )
return ( save_bw ( ofp , image_ID , drawable_ID ) ) ;
1999-01-04 06:41:12 +08:00
drawable = gimp_drawable_get ( drawable_ID ) ;
drawable_type = gimp_drawable_type ( drawable_ID ) ;
width = drawable - > width ;
height = drawable - > height ;
tile_height = gimp_tile_height ( ) ;
gimp_pixel_rgn_init ( & pixel_rgn , drawable , 0 , 0 , width , height , FALSE , FALSE ) ;
/* allocate a buffer for retrieving information from the pixel region */
2000-01-26 01:46:56 +08:00
src = data = ( guchar * ) g_malloc ( tile_height * width * drawable - > bpp ) ;
1997-11-25 06:05:25 +08:00
/* Set up transformation in PostScript */
1999-01-04 06:41:12 +08:00
save_ps_setup ( ofp , drawable_ID , width , height , 3 * 8 ) ;
1997-11-25 06:05:25 +08:00
/* Write read image procedure */
2000-01-23 06:26:20 +08:00
if ( ! level2 )
{
fprintf ( ofp , " { currentfile scanline readhexstring pop } false 3 \n " ) ;
}
else
{
2000-03-11 01:27:25 +08:00
fprintf ( ofp , " %% Strings to hold RGB-samples per scanline \n " ) ;
fprintf ( ofp , " /rstr %d string def \n " , width ) ;
fprintf ( ofp , " /gstr %d string def \n " , width ) ;
fprintf ( ofp , " /bstr %d string def \n " , width ) ;
fprintf ( ofp ,
" {currentfile /ASCII85Decode filter /RunLengthDecode filter \
rstr readstring pop } \ n " );
fprintf ( ofp ,
" {currentfile /ASCII85Decode filter /RunLengthDecode filter \
gstr readstring pop } \ n " );
fprintf ( ofp ,
" {currentfile /ASCII85Decode filter /RunLengthDecode filter \
bstr readstring pop } \ n " );
fprintf ( ofp , " true 3 \n " ) ;
/* Allocate buffer for packbits data. Worst case: Less than 1% increase */
packb = ( guchar * ) g_malloc ( ( width * 105 ) / 100 + 2 ) ;
plane = ( guchar * ) g_malloc ( width ) ;
2000-01-23 06:26:20 +08:00
}
2000-04-05 18:26:08 +08:00
ps_begin_data ( ofp ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " colorimage \n " ) ;
# define GET_INDEX_TILE(begin) \
{ int scan_lines ; \
scan_lines = ( i + tile_height - 1 < height ) ? tile_height : ( height - i ) ; \
gimp_pixel_rgn_get_rect ( & pixel_rgn , begin , 0 , i , width , scan_lines ) ; \
src = begin ; }
for ( i = 0 ; i < height ; i + + )
2000-01-23 06:26:20 +08:00
{
2000-01-26 01:46:56 +08:00
if ( ( i % tile_height ) = = 0 ) GET_INDEX_TILE ( data ) ; /* Get more data */
if ( ! level2 )
2006-05-08 20:23:32 +08:00
{
for ( j = 0 ; j < width ; j + + )
{
fwrite ( coltab + ( * ( src + + ) ) * 6 , 6 , 1 , ofp ) ;
if ( ( ( j + 1 ) % 13 ) = = 0 ) putc ( ' \n ' , ofp ) ;
}
putc ( ' \n ' , ofp ) ;
}
2000-01-26 01:46:56 +08:00
else
2000-03-11 01:27:25 +08:00
{ guchar * plane_ptr , * src_ptr ;
int rgb , nout ;
for ( rgb = 0 ; rgb < 3 ; rgb + + )
{
src_ptr = src ;
plane_ptr = plane ;
for ( j = 0 ; j < width ; j + + )
* ( plane_ptr + + ) = cmap_start [ 3 * * ( src_ptr + + ) + rgb ] ;
compress_packbits ( width , plane , & nout , packb ) ;
ascii85_init ( ) ;
ascii85_nout ( nout , packb , ofp ) ;
ascii85_out ( 128 , ofp ) ; /* Write EOD of RunLengthDecode filter */
ascii85_done ( ofp ) ;
}
src + = width ;
}
2003-06-13 22:37:00 +08:00
if ( ( i % 20 ) = = 0 )
2006-05-08 20:23:32 +08:00
gimp_progress_update ( ( double ) i / ( double ) height ) ;
1997-11-25 06:05:25 +08:00
}
2003-06-13 22:37:00 +08:00
2000-04-05 18:26:08 +08:00
ps_end_data ( ofp ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " showpage \n " ) ;
g_free ( data ) ;
2003-06-13 22:37:00 +08:00
if ( packb )
g_free ( packb ) ;
if ( plane )
g_free ( plane ) ;
1997-11-25 06:05:25 +08:00
gimp_drawable_detach ( drawable ) ;
if ( ferror ( ofp ) )
2000-01-26 01:46:56 +08:00
{
2004-05-24 05:12:29 +08:00
g_message ( _ ( " Write error occurred " ) ) ;
2004-11-19 05:10:12 +08:00
return FALSE ;
2000-01-26 01:46:56 +08:00
}
2004-11-19 05:10:12 +08:00
return TRUE ;
1997-11-25 06:05:25 +08:00
# undef GET_INDEX_TILE
}
static gint
2000-01-26 01:46:56 +08:00
save_rgb ( FILE * ofp ,
gint32 image_ID ,
gint32 drawable_ID )
1997-11-25 06:05:25 +08:00
{
int height , width , tile_height ;
int i , j ;
2000-01-26 01:46:56 +08:00
guchar * data , * src ;
2000-03-11 01:27:25 +08:00
guchar * packb = NULL , * plane = NULL ;
2000-08-22 09:26:57 +08:00
GimpPixelRgn pixel_rgn ;
GimpDrawable * drawable ;
GimpImageType drawable_type ;
1997-11-25 06:05:25 +08:00
static char * hex = " 0123456789abcdef " ;
2000-01-23 06:26:20 +08:00
int level2 = ( psvals . level > 1 ) ;
1997-11-25 06:05:25 +08:00
drawable = gimp_drawable_get ( drawable_ID ) ;
drawable_type = gimp_drawable_type ( drawable_ID ) ;
width = drawable - > width ;
height = drawable - > height ;
tile_height = gimp_tile_height ( ) ;
gimp_pixel_rgn_init ( & pixel_rgn , drawable , 0 , 0 , width , height , FALSE , FALSE ) ;
/* allocate a buffer for retrieving information from the pixel region */
2000-01-26 01:46:56 +08:00
src = data = ( guchar * ) g_malloc ( tile_height * width * drawable - > bpp ) ;
1997-11-25 06:05:25 +08:00
/* Set up transformation in PostScript */
1999-01-04 06:41:12 +08:00
save_ps_setup ( ofp , drawable_ID , width , height , 3 * 8 ) ;
1997-11-25 06:05:25 +08:00
/* Write read image procedure */
2000-01-23 06:26:20 +08:00
if ( ! level2 )
{
fprintf ( ofp , " { currentfile scanline readhexstring pop } false 3 \n " ) ;
}
else
{
2000-03-11 01:27:25 +08:00
fprintf ( ofp , " %% Strings to hold RGB-samples per scanline \n " ) ;
fprintf ( ofp , " /rstr %d string def \n " , width ) ;
fprintf ( ofp , " /gstr %d string def \n " , width ) ;
fprintf ( ofp , " /bstr %d string def \n " , width ) ;
fprintf ( ofp ,
" {currentfile /ASCII85Decode filter /RunLengthDecode filter \
rstr readstring pop } \ n " );
fprintf ( ofp ,
" {currentfile /ASCII85Decode filter /RunLengthDecode filter \
gstr readstring pop } \ n " );
fprintf ( ofp ,
" {currentfile /ASCII85Decode filter /RunLengthDecode filter \
bstr readstring pop } \ n " );
fprintf ( ofp , " true 3 \n " ) ;
/* Allocate buffer for packbits data. Worst case: Less than 1% increase */
packb = ( guchar * ) g_malloc ( ( width * 105 ) / 100 + 2 ) ;
plane = ( guchar * ) g_malloc ( width ) ;
2000-01-23 06:26:20 +08:00
}
2000-04-05 18:26:08 +08:00
ps_begin_data ( ofp ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " colorimage \n " ) ;
# define GET_RGB_TILE(begin) \
{ int scan_lines ; \
scan_lines = ( i + tile_height - 1 < height ) ? tile_height : ( height - i ) ; \
gimp_pixel_rgn_get_rect ( & pixel_rgn , begin , 0 , i , width , scan_lines ) ; \
src = begin ; }
for ( i = 0 ; i < height ; i + + )
{
2000-01-26 01:46:56 +08:00
if ( ( i % tile_height ) = = 0 ) GET_RGB_TILE ( data ) ; /* Get more data */
if ( ! level2 )
2006-05-08 20:23:32 +08:00
{
for ( j = 0 ; j < width ; j + + )
{
putc ( hex [ ( * src ) > > 4 ] , ofp ) ; /* Red */
putc ( hex [ ( * ( src + + ) ) & 0x0f ] , ofp ) ;
putc ( hex [ ( * src ) > > 4 ] , ofp ) ; /* Green */
putc ( hex [ ( * ( src + + ) ) & 0x0f ] , ofp ) ;
putc ( hex [ ( * src ) > > 4 ] , ofp ) ; /* Blue */
putc ( hex [ ( * ( src + + ) ) & 0x0f ] , ofp ) ;
if ( ( ( j + 1 ) % 13 ) = = 0 ) putc ( ' \n ' , ofp ) ;
}
putc ( ' \n ' , ofp ) ;
}
2000-01-26 01:46:56 +08:00
else
2006-05-08 20:23:32 +08:00
{ guchar * plane_ptr , * src_ptr ;
2000-03-11 01:27:25 +08:00
int rgb , nout ;
for ( rgb = 0 ; rgb < 3 ; rgb + + )
{
src_ptr = src + rgb ;
plane_ptr = plane ;
for ( j = 0 ; j < width ; j + + )
2006-05-08 20:23:32 +08:00
{
2000-03-11 01:27:25 +08:00
* ( plane_ptr + + ) = * src_ptr ;
src_ptr + = 3 ;
}
compress_packbits ( width , plane , & nout , packb ) ;
ascii85_init ( ) ;
2006-05-08 20:23:32 +08:00
ascii85_nout ( nout , packb , ofp ) ;
2000-03-11 01:27:25 +08:00
ascii85_out ( 128 , ofp ) ; /* Write EOD of RunLengthDecode filter */
ascii85_done ( ofp ) ;
}
src + = 3 * width ;
2006-05-08 20:23:32 +08:00
}
2003-06-13 22:37:00 +08:00
if ( ( i % 20 ) = = 0 )
2006-05-08 20:23:32 +08:00
gimp_progress_update ( ( double ) i / ( double ) height ) ;
1997-11-25 06:05:25 +08:00
}
2003-06-13 22:37:00 +08:00
2000-04-05 18:26:08 +08:00
ps_end_data ( ofp ) ;
1997-11-25 06:05:25 +08:00
fprintf ( ofp , " showpage \n " ) ;
g_free ( data ) ;
2003-06-13 22:37:00 +08:00
if ( packb )
g_free ( packb ) ;
if ( plane )
g_free ( plane ) ;
1997-11-25 06:05:25 +08:00
gimp_drawable_detach ( drawable ) ;
if ( ferror ( ofp ) )
2000-01-26 01:46:56 +08:00
{
2004-05-24 05:12:29 +08:00
g_message ( _ ( " Write error occurred " ) ) ;
2004-11-19 05:10:12 +08:00
return FALSE ;
2000-01-26 01:46:56 +08:00
}
2004-11-19 05:10:12 +08:00
return TRUE ;
1997-11-25 06:05:25 +08:00
# undef GET_RGB_TILE
}
/* Load interface functions */
2005-08-15 16:48:45 +08:00
static gint32
count_ps_pages ( const gchar * filename )
{
FILE * psfile = NULL ;
gchar * curr_line = NULL ;
gint32 num_pages = 0 ;
gint32 showpage_count = 0 ;
if ( strncmp ( g_ascii_strup ( filename + ( strlen ( filename ) - 3 ) , 3 ) , " EPS " , 3 ) = = 0 )
return 1 ;
psfile = g_fopen ( filename , " r " ) ;
if ( psfile = = NULL )
{
g_message ( _ ( " Could not open '%s' for reading: %s " ) ,
gimp_filename_to_utf8 ( filename ) , g_strerror ( errno ) ) ;
return 0 ;
}
curr_line = g_malloc0 ( 1024 * sizeof ( gchar ) ) ;
while ( num_pages = = 0 & & ! feof ( psfile ) )
{
fgets ( curr_line , 1023 , psfile ) ;
if ( strncmp ( curr_line + 2 , " Pages: " , 6 ) = = 0 )
sscanf ( curr_line + strlen ( " %%Pages: " ) , " %d " , & num_pages ) ;
else if ( strncmp ( curr_line , " showpage " , 8 ) = = 0 )
showpage_count + + ;
}
if ( feof ( psfile ) & & num_pages < 1 & & showpage_count > 0 )
num_pages = showpage_count ;
g_free ( curr_line ) ;
fclose ( psfile ) ;
return num_pages ;
}
2004-05-20 01:53:21 +08:00
static gboolean
2005-08-15 16:48:45 +08:00
load_dialog ( const gchar * filename ,
gboolean loadPDF )
1997-11-25 06:05:25 +08:00
{
2000-01-26 01:46:56 +08:00
GtkWidget * dialog ;
2000-01-08 23:23:28 +08:00
GtkWidget * main_vbox ;
1997-11-25 06:05:25 +08:00
GtkWidget * hbox ;
2000-01-26 01:46:56 +08:00
GtkWidget * frame ;
GtkWidget * vbox ;
1997-11-25 06:05:25 +08:00
GtkWidget * table ;
2000-01-26 01:46:56 +08:00
GtkWidget * spinbutton ;
GtkObject * adj ;
2005-08-15 16:48:45 +08:00
GtkWidget * entry = NULL ;
GtkWidget * target = NULL ;
2000-01-26 01:46:56 +08:00
GtkWidget * toggle ;
2005-08-15 16:48:45 +08:00
GtkWidget * selector = NULL ;
gint32 page_count ;
gchar * range = NULL ;
2003-11-06 23:27:05 +08:00
gboolean run ;
1997-11-25 06:05:25 +08:00
2005-08-15 16:48:45 +08:00
page_count = count_ps_pages ( filename ) ;
2005-08-15 18:30:39 +08:00
gimp_ui_init ( PLUG_IN_BINARY , FALSE ) ;
1997-11-25 06:05:25 +08:00
2005-09-02 19:09:03 +08:00
dialog = gimp_dialog_new ( _ ( " Import from PostScript " ) , PLUG_IN_BINARY ,
2003-11-06 23:27:05 +08:00
NULL , 0 ,
2006-05-08 20:23:32 +08:00
gimp_standard_help_func , LOAD_PS_PROC ,
2000-01-08 23:23:28 +08:00
2006-05-08 20:23:32 +08:00
GTK_STOCK_CANCEL , GTK_RESPONSE_CANCEL ,
_ ( " _Import " ) , GTK_RESPONSE_OK ,
2000-01-08 23:23:28 +08:00
2006-05-08 20:23:32 +08:00
NULL ) ;
2000-01-08 23:23:28 +08:00
2005-02-09 04:40:33 +08:00
gtk_dialog_set_alternative_button_order ( GTK_DIALOG ( dialog ) ,
2005-08-15 16:48:45 +08:00
GTK_RESPONSE_OK ,
GTK_RESPONSE_CANCEL ,
- 1 ) ;
2005-02-09 04:40:33 +08:00
2004-05-20 01:53:21 +08:00
main_vbox = gtk_vbox_new ( FALSE , 12 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( main_vbox ) , 12 ) ;
2000-01-26 01:46:56 +08:00
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog ) - > vbox ) , main_vbox ,
2005-08-15 16:48:45 +08:00
TRUE , TRUE , 0 ) ;
2000-01-08 23:23:28 +08:00
gtk_widget_show ( main_vbox ) ;
2005-08-15 16:48:45 +08:00
if ( page_count > 1 )
{
selector = gimp_page_selector_new ( ) ;
gtk_box_pack_start ( GTK_BOX ( main_vbox ) , selector , TRUE , TRUE , 0 ) ;
gimp_page_selector_set_n_pages ( GIMP_PAGE_SELECTOR ( selector ) ,
2006-05-08 20:23:32 +08:00
page_count ) ;
2005-08-15 16:48:45 +08:00
gimp_page_selector_set_target ( GIMP_PAGE_SELECTOR ( selector ) ,
2006-05-08 20:23:32 +08:00
ps_pagemode ) ;
2005-10-28 22:57:32 +08:00
2005-08-15 16:48:45 +08:00
gtk_widget_show ( selector ) ;
2005-10-28 22:57:32 +08:00
g_signal_connect_swapped ( selector , " activate " ,
G_CALLBACK ( gtk_window_activate_default ) ,
dialog ) ;
2005-08-15 16:48:45 +08:00
}
2004-05-20 01:53:21 +08:00
hbox = gtk_hbox_new ( TRUE , 12 ) ;
2000-01-08 23:23:28 +08:00
gtk_box_pack_start ( GTK_BOX ( main_vbox ) , hbox , FALSE , FALSE , 0 ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( hbox ) ;
/* Rendering */
2004-05-20 01:53:21 +08:00
frame = gimp_frame_new ( _ ( " Rendering " ) ) ;
gtk_box_pack_start ( GTK_BOX ( hbox ) , frame , FALSE , TRUE , 0 ) ;
2000-01-08 23:23:28 +08:00
2004-05-20 01:53:21 +08:00
vbox = gtk_vbox_new ( FALSE , 6 ) ;
1997-11-25 06:05:25 +08:00
gtk_container_add ( GTK_CONTAINER ( frame ) , vbox ) ;
/* Resolution/Width/Height/Pages labels */
2000-01-26 01:46:56 +08:00
table = gtk_table_new ( 4 , 2 , FALSE ) ;
2004-05-20 01:53:21 +08:00
gtk_table_set_row_spacings ( GTK_TABLE ( table ) , 6 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( table ) , 6 ) ;
2000-01-26 01:46:56 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , table , FALSE , FALSE , 0 ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( table ) ;
2000-01-26 01:46:56 +08:00
spinbutton = gimp_spin_button_new ( & adj , plvals . resolution ,
2006-05-08 20:23:32 +08:00
5 , 1440 , 1 , 10 , 0 , 1 , 0 ) ;
2000-01-31 11:13:02 +08:00
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 0 ,
2006-05-08 20:23:32 +08:00
_ ( " Resolution: " ) , 0.0 , 0.5 ,
spinbutton , 1 , FALSE ) ;
2005-07-01 00:03:24 +08:00
g_signal_connect ( adj , " value-changed " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_int_adjustment_update ) ,
& plvals . resolution ) ;
2000-01-26 01:46:56 +08:00
spinbutton = gimp_spin_button_new ( & adj , plvals . width ,
2006-05-08 20:23:32 +08:00
1 , GIMP_MAX_IMAGE_SIZE , 1 , 10 , 0 , 1 , 0 ) ;
2000-01-31 11:13:02 +08:00
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 1 ,
2006-05-08 20:23:32 +08:00
_ ( " _Width: " ) , 0.0 , 0.5 ,
spinbutton , 1 , FALSE ) ;
2005-07-01 00:03:24 +08:00
g_signal_connect ( adj , " value-changed " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_int_adjustment_update ) ,
& plvals . width ) ;
2000-01-26 01:46:56 +08:00
spinbutton = gimp_spin_button_new ( & adj , plvals . height ,
2006-05-08 20:23:32 +08:00
1 , GIMP_MAX_IMAGE_SIZE , 1 , 10 , 0 , 1 , 0 ) ;
2000-01-31 11:13:02 +08:00
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 2 ,
2006-05-08 20:23:32 +08:00
_ ( " _Height: " ) , 0.0 , 0.5 ,
spinbutton , 1 , FALSE ) ;
2005-07-01 00:03:24 +08:00
g_signal_connect ( adj , " value-changed " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_int_adjustment_update ) ,
& plvals . height ) ;
2000-01-26 01:46:56 +08:00
2005-08-15 16:48:45 +08:00
if ( loadPDF | | page_count = = 0 )
{
entry = gtk_entry_new ( ) ;
gtk_widget_set_size_request ( entry , 80 , - 1 ) ;
gtk_entry_set_text ( GTK_ENTRY ( entry ) , plvals . pages ) ;
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 3 ,
2006-05-08 20:23:32 +08:00
_ ( " Pages: " ) , 0.0 , 0.5 ,
entry , 1 , FALSE ) ;
2005-08-15 16:48:45 +08:00
g_signal_connect ( entry , " changed " ,
G_CALLBACK ( load_pages_entry_callback ) ,
NULL ) ;
gimp_help_set_help_data ( GTK_WIDGET ( entry ) ,
_ ( " Pages to load (e.g.: 1-4 or 1,3,5-7) " ) , NULL ) ;
target = gtk_combo_box_new_text ( ) ;
gtk_combo_box_insert_text ( GTK_COMBO_BOX ( target ) ,
2006-05-08 20:23:32 +08:00
GIMP_PAGE_SELECTOR_TARGET_LAYERS , _ ( " Layers " ) ) ;
2005-08-15 16:48:45 +08:00
gtk_combo_box_insert_text ( GTK_COMBO_BOX ( target ) ,
2006-05-08 20:23:32 +08:00
GIMP_PAGE_SELECTOR_TARGET_IMAGES , _ ( " Images " ) ) ;
2005-08-15 16:48:45 +08:00
gtk_combo_box_set_active ( GTK_COMBO_BOX ( target ) , ( int ) ps_pagemode ) ;
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 4 ,
2006-05-08 20:23:32 +08:00
_ ( " Open as " ) , 0.0 , 0.5 ,
target , 1 , FALSE ) ;
2005-08-15 16:48:45 +08:00
}
1997-11-25 06:05:25 +08:00
2000-01-08 23:23:28 +08:00
toggle = gtk_check_button_new_with_label ( _ ( " Try Bounding Box " ) ) ;
2000-01-26 01:46:56 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , toggle , FALSE , FALSE , 0 ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( toggle ) , plvals . use_bbox ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( toggle ) ;
2003-01-07 14:16:02 +08:00
g_signal_connect ( toggle , " toggled " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_toggle_button_update ) ,
& plvals . use_bbox ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( vbox ) ;
gtk_widget_show ( frame ) ;
/* Colouring */
2003-11-15 02:05:39 +08:00
frame = gimp_int_radio_group_new ( TRUE , _ ( " Coloring " ) ,
2006-05-08 20:23:32 +08:00
G_CALLBACK ( gimp_radio_button_update ) ,
& plvals . pnm_type , plvals . pnm_type ,
2000-01-08 23:23:28 +08:00
2006-05-08 20:23:32 +08:00
_ ( " B/W " ) , 4 , NULL ,
_ ( " Gray " ) , 5 , NULL ,
_ ( " Color " ) , 6 , NULL ,
_ ( " Automatic " ) , 7 , NULL ,
1997-11-25 06:05:25 +08:00
2006-05-08 20:23:32 +08:00
NULL ) ;
2004-05-20 01:53:21 +08:00
gtk_box_pack_start ( GTK_BOX ( hbox ) , frame , FALSE , TRUE , 0 ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( frame ) ;
2004-05-20 01:53:21 +08:00
hbox = gtk_hbox_new ( TRUE , 12 ) ;
2000-01-08 23:23:28 +08:00
gtk_box_pack_start ( GTK_BOX ( main_vbox ) , hbox , FALSE , FALSE , 0 ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( hbox ) ;
2004-06-22 03:15:08 +08:00
frame = gimp_int_radio_group_new ( TRUE , _ ( " Text antialiasing " ) ,
2006-05-08 20:23:32 +08:00
G_CALLBACK ( gimp_radio_button_update ) ,
& plvals . textalpha , plvals . textalpha ,
1997-11-25 06:05:25 +08:00
2006-05-08 20:23:32 +08:00
_ ( " None " ) , 1 , NULL ,
_ ( " Weak " ) , 2 , NULL ,
_ ( " Strong " ) , 4 , NULL ,
2000-01-26 01:46:56 +08:00
2006-05-08 20:23:32 +08:00
NULL ) ;
2000-01-26 01:46:56 +08:00
gtk_box_pack_start ( GTK_BOX ( hbox ) , frame , FALSE , TRUE , 0 ) ;
gtk_widget_show ( frame ) ;
2004-06-22 03:15:08 +08:00
frame = gimp_int_radio_group_new ( TRUE , _ ( " Graphic antialiasing " ) ,
2006-05-08 20:23:32 +08:00
G_CALLBACK ( gimp_radio_button_update ) ,
& plvals . graphicsalpha , plvals . graphicsalpha ,
2000-01-26 01:46:56 +08:00
2006-05-08 20:23:32 +08:00
_ ( " None " ) , 1 , NULL ,
_ ( " Weak " ) , 2 , NULL ,
_ ( " Strong " ) , 4 , NULL ,
1997-11-25 06:05:25 +08:00
2006-05-08 20:23:32 +08:00
NULL ) ;
2000-01-26 01:46:56 +08:00
gtk_box_pack_start ( GTK_BOX ( hbox ) , frame , FALSE , TRUE , 0 ) ;
gtk_widget_show ( frame ) ;
gtk_widget_show ( dialog ) ;
1997-11-25 06:05:25 +08:00
2003-11-12 02:11:56 +08:00
run = ( gimp_dialog_run ( GIMP_DIALOG ( dialog ) ) = = GTK_RESPONSE_OK ) ;
1997-11-25 06:05:25 +08:00
2005-10-28 22:57:32 +08:00
if ( selector )
2005-08-15 16:48:45 +08:00
{
range = gimp_page_selector_get_selected_range ( GIMP_PAGE_SELECTOR ( selector ) ) ;
if ( strlen ( range ) < 1 )
{
gimp_page_selector_select_all ( GIMP_PAGE_SELECTOR ( selector ) ) ;
range = gimp_page_selector_get_selected_range ( GIMP_PAGE_SELECTOR ( selector ) ) ;
}
strncpy ( plvals . pages , range , sizeof ( plvals . pages ) ) ;
plvals . pages [ strlen ( range ) ] = ' \0 ' ;
ps_pagemode = gimp_page_selector_get_target ( GIMP_PAGE_SELECTOR ( selector ) ) ;
}
else if ( loadPDF | | page_count = = 0 )
{
ps_pagemode = gtk_combo_box_get_active ( GTK_COMBO_BOX ( target ) ) ;
}
else
{
strncpy ( plvals . pages , " 1 " , 1 ) ;
plvals . pages [ 1 ] = ' \0 ' ;
ps_pagemode = GIMP_PAGE_SELECTOR_TARGET_IMAGES ;
}
2003-11-06 23:27:05 +08:00
gtk_widget_destroy ( dialog ) ;
1997-11-25 06:05:25 +08:00
2003-11-06 23:27:05 +08:00
return run ;
2000-01-26 01:46:56 +08:00
}
1997-11-25 06:05:25 +08:00
static void
2000-01-26 01:46:56 +08:00
load_pages_entry_callback ( GtkWidget * widget ,
2006-05-08 20:23:32 +08:00
gpointer data )
1997-11-25 06:05:25 +08:00
{
2004-11-19 05:36:10 +08:00
gsize nelem = sizeof ( plvals . pages ) ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
strncpy ( plvals . pages , gtk_entry_get_text ( GTK_ENTRY ( widget ) ) , nelem ) ;
plvals . pages [ nelem - 1 ] = ' \0 ' ;
1997-11-25 06:05:25 +08:00
}
2003-11-06 23:27:05 +08:00
1997-11-25 06:05:25 +08:00
/* Save interface functions */
2004-05-20 01:53:21 +08:00
static gboolean
1997-11-25 06:05:25 +08:00
save_dialog ( void )
{
SaveDialogVals * vals ;
2000-01-26 01:46:56 +08:00
GtkWidget * dialog ;
1997-11-25 06:05:25 +08:00
GtkWidget * toggle ;
GtkWidget * frame , * uframe ;
2000-01-26 01:46:56 +08:00
GtkWidget * hbox , * vbox ;
1997-12-26 15:08:20 +08:00
GtkWidget * main_vbox [ 2 ] ;
1997-11-25 06:05:25 +08:00
GtkWidget * table ;
2000-01-26 01:46:56 +08:00
GtkWidget * spinbutton ;
GtkObject * adj ;
gint j ;
2003-11-06 23:27:05 +08:00
gboolean run ;
2000-01-08 23:23:28 +08:00
2000-07-31 06:48:35 +08:00
vals = g_new ( SaveDialogVals , 1 ) ;
2000-01-26 01:46:56 +08:00
vals - > level = ( psvals . level > 1 ) ;
2000-01-08 23:23:28 +08:00
2005-08-15 18:30:39 +08:00
dialog = gimp_dialog_new ( _ ( " Save as PostScript " ) , PLUG_IN_BINARY ,
2003-11-06 23:27:05 +08:00
NULL , 0 ,
2006-05-08 20:23:32 +08:00
gimp_standard_help_func , SAVE_PS_PROC ,
2000-01-26 01:46:56 +08:00
2006-05-08 20:23:32 +08:00
GTK_STOCK_CANCEL , GTK_RESPONSE_CANCEL ,
GTK_STOCK_SAVE , GTK_RESPONSE_OK ,
2000-01-26 01:46:56 +08:00
2006-05-08 20:23:32 +08:00
NULL ) ;
2000-01-26 01:46:56 +08:00
2005-08-15 18:30:39 +08:00
gtk_dialog_set_alternative_button_order ( GTK_DIALOG ( dialog ) ,
GTK_RESPONSE_OK ,
GTK_RESPONSE_CANCEL ,
- 1 ) ;
2005-09-10 02:38:00 +08:00
gimp_window_set_transient ( GTK_WINDOW ( dialog ) ) ;
1997-12-26 15:08:20 +08:00
/* Main hbox */
2004-05-20 01:53:21 +08:00
hbox = gtk_hbox_new ( FALSE , 12 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( hbox ) , 12 ) ;
2000-01-26 01:46:56 +08:00
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog ) - > vbox ) , hbox ,
2000-01-08 23:23:28 +08:00
FALSE , FALSE , 0 ) ;
1997-12-26 15:08:20 +08:00
main_vbox [ 0 ] = main_vbox [ 1 ] = NULL ;
2001-12-06 10:28:58 +08:00
for ( j = 0 ; j < G_N_ELEMENTS ( main_vbox ) ; j + + )
2000-01-08 23:23:28 +08:00
{
2004-05-20 01:53:21 +08:00
main_vbox [ j ] = gtk_vbox_new ( FALSE , 12 ) ;
gtk_box_pack_start ( GTK_BOX ( hbox ) , main_vbox [ j ] , FALSE , TRUE , 0 ) ;
gtk_widget_show ( main_vbox [ j ] ) ;
2000-01-08 23:23:28 +08:00
}
1997-12-26 15:08:20 +08:00
1997-11-25 06:05:25 +08:00
/* Image Size */
2004-05-20 01:53:21 +08:00
frame = gimp_frame_new ( _ ( " Image Size " ) ) ;
gtk_box_pack_start ( GTK_BOX ( main_vbox [ 0 ] ) , frame , FALSE , TRUE , 0 ) ;
2000-01-26 01:46:56 +08:00
2004-05-20 01:53:21 +08:00
vbox = gtk_vbox_new ( FALSE , 6 ) ;
1997-11-25 06:05:25 +08:00
gtk_container_add ( GTK_CONTAINER ( frame ) , vbox ) ;
/* Width/Height/X-/Y-offset labels */
table = gtk_table_new ( 4 , 2 , FALSE ) ;
2004-05-20 01:53:21 +08:00
gtk_table_set_row_spacings ( GTK_TABLE ( table ) , 6 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( table ) , 6 ) ;
2000-01-26 01:46:56 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , table , FALSE , FALSE , 0 ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( table ) ;
2000-01-26 01:46:56 +08:00
spinbutton = gimp_spin_button_new ( & vals - > adjustment [ 0 ] , psvals . width ,
2006-05-08 20:23:32 +08:00
1e-5 , GIMP_MAX_IMAGE_SIZE , 1 , 10 , 0 , 1 , 2 ) ;
2000-01-31 11:13:02 +08:00
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 0 ,
2006-05-08 20:23:32 +08:00
_ ( " _Width: " ) , 0.0 , 0.5 ,
spinbutton , 1 , FALSE ) ;
2005-07-01 00:03:24 +08:00
g_signal_connect ( vals - > adjustment [ 0 ] , " value-changed " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_double_adjustment_update ) ,
& psvals . width ) ;
2000-01-26 01:46:56 +08:00
spinbutton = gimp_spin_button_new ( & vals - > adjustment [ 1 ] , psvals . height ,
2006-05-08 20:23:32 +08:00
1e-5 , GIMP_MAX_IMAGE_SIZE , 1 , 10 , 0 , 1 , 2 ) ;
2000-01-31 11:13:02 +08:00
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 1 ,
2006-05-08 20:23:32 +08:00
_ ( " _Height: " ) , 0.0 , 0.5 ,
spinbutton , 1 , FALSE ) ;
2005-07-01 00:03:24 +08:00
g_signal_connect ( vals - > adjustment [ 1 ] , " value-changed " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_double_adjustment_update ) ,
& psvals . height ) ;
2000-01-26 01:46:56 +08:00
spinbutton = gimp_spin_button_new ( & vals - > adjustment [ 2 ] , psvals . x_offset ,
2006-05-08 20:23:32 +08:00
0.0 , GIMP_MAX_IMAGE_SIZE , 1 , 10 , 0 , 1 , 2 ) ;
2000-01-31 11:13:02 +08:00
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 2 ,
2006-05-08 20:23:32 +08:00
_ ( " _X offset: " ) , 0.0 , 0.5 ,
spinbutton , 1 , FALSE ) ;
2005-07-01 00:03:24 +08:00
g_signal_connect ( vals - > adjustment [ 2 ] , " value-changed " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_double_adjustment_update ) ,
& psvals . x_offset ) ;
2000-01-26 01:46:56 +08:00
spinbutton = gimp_spin_button_new ( & vals - > adjustment [ 3 ] , psvals . y_offset ,
2006-05-08 20:23:32 +08:00
0.0 , GIMP_MAX_IMAGE_SIZE , 1 , 10 , 0 , 1 , 2 ) ;
2000-01-31 11:13:02 +08:00
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 3 ,
2006-05-08 20:23:32 +08:00
_ ( " _Y offset: " ) , 0.0 , 0.5 ,
spinbutton , 1 , FALSE ) ;
2005-07-01 00:03:24 +08:00
g_signal_connect ( vals - > adjustment [ 3 ] , " value-changed " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_double_adjustment_update ) ,
& psvals . y_offset ) ;
1997-11-25 06:05:25 +08:00
2004-06-22 03:15:08 +08:00
toggle = gtk_check_button_new_with_mnemonic ( _ ( " _Keep aspect ratio " ) ) ;
2004-05-20 01:53:21 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , toggle , FALSE , FALSE , 0 ) ;
2000-01-26 01:46:56 +08:00
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( toggle ) , psvals . keep_ratio ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( toggle ) ;
2001-12-31 08:21:10 +08:00
gimp_help_set_help_data ( toggle ,
2006-08-29 21:32:22 +08:00
_ ( " When toggled, the resulting image will be "
" scaled to fit into the given size without "
" changing the aspect ratio. " ) ,
2006-05-08 20:23:32 +08:00
" #keep_aspect_ratio " ) ,
2001-12-31 08:21:10 +08:00
2003-01-07 14:16:02 +08:00
g_signal_connect ( toggle , " toggled " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_toggle_button_update ) ,
& psvals . keep_ratio ) ;
1997-11-25 06:05:25 +08:00
/* Unit */
2003-11-15 02:05:39 +08:00
uframe = gimp_int_radio_group_new ( TRUE , _ ( " Unit " ) ,
2006-05-08 20:23:32 +08:00
G_CALLBACK ( save_unit_toggle_update ) ,
vals , psvals . unit_mm ,
2001-12-31 08:21:10 +08:00
2006-05-08 20:23:32 +08:00
_ ( " _Inch " ) , FALSE , NULL ,
_ ( " _Millimeter " ) , TRUE , NULL ,
1997-11-25 06:05:25 +08:00
2006-05-08 20:23:32 +08:00
NULL ) ;
2001-12-31 08:21:10 +08:00
2004-05-20 01:53:21 +08:00
gtk_box_pack_start ( GTK_BOX ( main_vbox [ 0 ] ) , uframe , TRUE , TRUE , 0 ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( uframe ) ;
gtk_widget_show ( vbox ) ;
gtk_widget_show ( frame ) ;
/* Rotation */
2003-11-15 02:05:39 +08:00
frame = gimp_int_radio_group_new ( TRUE , _ ( " Rotation " ) ,
2006-05-08 20:23:32 +08:00
G_CALLBACK ( gimp_radio_button_update ) ,
& psvals . rotate , psvals . rotate ,
2000-01-08 23:23:28 +08:00
2006-05-08 20:23:32 +08:00
" _0 " , 0 , NULL ,
" _90 " , 90 , NULL ,
" _180 " , 180 , NULL ,
" _270 " , 270 , NULL ,
1997-11-25 06:05:25 +08:00
2006-05-08 20:23:32 +08:00
NULL ) ;
2001-12-31 08:21:10 +08:00
2004-05-20 01:53:21 +08:00
gtk_box_pack_start ( GTK_BOX ( main_vbox [ 1 ] ) , frame , TRUE , TRUE , 0 ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( frame ) ;
1997-12-26 15:08:20 +08:00
/* Format */
2004-05-20 01:53:21 +08:00
frame = gimp_frame_new ( _ ( " Output " ) ) ;
1997-12-26 15:08:20 +08:00
gtk_box_pack_start ( GTK_BOX ( main_vbox [ 1 ] ) , frame , TRUE , TRUE , 0 ) ;
2000-01-08 23:23:28 +08:00
2004-05-20 01:53:21 +08:00
vbox = gtk_vbox_new ( FALSE , 6 ) ;
1997-12-26 15:08:20 +08:00
gtk_container_add ( GTK_CONTAINER ( frame ) , vbox ) ;
2004-06-22 03:15:08 +08:00
toggle = gtk_check_button_new_with_mnemonic ( _ ( " _PostScript level 2 " ) ) ;
2004-05-20 01:53:21 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , toggle , FALSE , FALSE , 0 ) ;
2000-01-23 06:26:20 +08:00
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( toggle ) , vals - > level ) ;
gtk_widget_show ( toggle ) ;
2003-01-07 14:16:02 +08:00
g_signal_connect ( toggle , " toggled " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_toggle_button_update ) ,
& vals - > level ) ;
2003-01-19 22:40:56 +08:00
toggle = gtk_check_button_new_with_mnemonic ( _ ( " _Encapsulated PostScript " ) ) ;
2004-05-20 01:53:21 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , toggle , FALSE , FALSE , 0 ) ;
2000-01-26 01:46:56 +08:00
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( toggle ) , psvals . eps ) ;
1997-12-26 15:08:20 +08:00
gtk_widget_show ( toggle ) ;
2003-01-07 14:16:02 +08:00
g_signal_connect ( toggle , " toggled " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_toggle_button_update ) ,
& psvals . eps ) ;
2003-01-19 22:40:56 +08:00
toggle = gtk_check_button_new_with_mnemonic ( _ ( " P_review " ) ) ;
2004-05-20 01:53:21 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , toggle , FALSE , FALSE , 0 ) ;
2000-01-26 01:46:56 +08:00
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( toggle ) , psvals . preview ) ;
1997-12-26 15:08:20 +08:00
gtk_widget_show ( toggle ) ;
2003-01-07 14:16:02 +08:00
g_signal_connect ( toggle , " toggled " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_toggle_button_update ) ,
& psvals . preview ) ;
1997-12-26 15:08:20 +08:00
/* Preview size label/entry */
table = gtk_table_new ( 1 , 2 , FALSE ) ;
2004-05-20 01:53:21 +08:00
gtk_table_set_col_spacings ( GTK_TABLE ( table ) , 6 ) ;
2000-01-26 01:46:56 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , table , FALSE , FALSE , 0 ) ;
1997-12-26 15:08:20 +08:00
gtk_widget_show ( table ) ;
2001-12-31 08:21:10 +08:00
g_object_set_data ( G_OBJECT ( toggle ) , " set_sensitive " , table ) ;
2000-01-26 01:46:56 +08:00
gtk_widget_set_sensitive ( table , psvals . preview ) ;
spinbutton = gimp_spin_button_new ( & adj , psvals . preview_size ,
2006-05-08 20:23:32 +08:00
0 , 1024 , 1 , 10 , 0 , 1 , 0 ) ;
2000-01-31 11:13:02 +08:00
gimp_table_attach_aligned ( GTK_TABLE ( table ) , 0 , 0 ,
2006-05-08 20:23:32 +08:00
_ ( " Preview _size: " ) , 1.0 , 0.5 ,
spinbutton , 1 , FALSE ) ;
2000-01-26 01:46:56 +08:00
gtk_widget_show ( spinbutton ) ;
1997-12-26 15:08:20 +08:00
2005-07-01 00:03:24 +08:00
g_signal_connect ( adj , " value-changed " ,
2001-12-31 08:21:10 +08:00
G_CALLBACK ( gimp_int_adjustment_update ) ,
& psvals . preview_size ) ;
1997-12-26 15:08:20 +08:00
gtk_widget_show ( vbox ) ;
gtk_widget_show ( frame ) ;
gtk_widget_show ( hbox ) ;
2000-01-26 01:46:56 +08:00
gtk_widget_show ( dialog ) ;
1997-11-25 06:05:25 +08:00
2003-11-12 02:11:56 +08:00
run = ( gimp_dialog_run ( GIMP_DIALOG ( dialog ) ) = = GTK_RESPONSE_OK ) ;
2003-11-06 23:27:05 +08:00
gtk_widget_destroy ( dialog ) ;
1997-11-25 06:05:25 +08:00
2000-03-11 01:27:25 +08:00
psvals . level = ( vals - > level ) ? 2 : 1 ;
2000-01-26 01:46:56 +08:00
1997-11-25 06:05:25 +08:00
g_free ( vals ) ;
2003-11-06 23:27:05 +08:00
return run ;
2000-01-26 01:46:56 +08:00
}
1997-11-25 06:05:25 +08:00
static void
2000-01-26 01:46:56 +08:00
save_unit_toggle_update ( GtkWidget * widget ,
2006-05-08 20:23:32 +08:00
gpointer data )
1997-11-25 06:05:25 +08:00
{
2000-01-26 01:46:56 +08:00
if ( GTK_TOGGLE_BUTTON ( widget ) - > active )
{
SaveDialogVals * vals ;
gdouble factor ;
gdouble value ;
gint unit_mm ;
gint i ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
vals = ( SaveDialogVals * ) data ;
2001-12-31 08:21:10 +08:00
unit_mm = GPOINTER_TO_INT ( g_object_get_data ( G_OBJECT ( widget ) ,
" gimp-item-data " ) ) ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
psvals . unit_mm = unit_mm ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
if ( unit_mm )
2006-05-08 20:23:32 +08:00
factor = 25.4 ;
2000-01-26 01:46:56 +08:00
else
2006-05-08 20:23:32 +08:00
factor = 1.0 / 25.4 ;
1997-11-25 06:05:25 +08:00
2000-01-26 01:46:56 +08:00
for ( i = 0 ; i < 4 ; i + + )
2006-05-08 20:23:32 +08:00
{
value = GTK_ADJUSTMENT ( vals - > adjustment [ i ] ) - > value * factor ;
2000-01-26 01:46:56 +08:00
2006-08-29 21:32:22 +08:00
gtk_adjustment_set_value ( GTK_ADJUSTMENT ( vals - > adjustment [ i ] ) ,
value ) ;
2006-05-08 20:23:32 +08:00
}
1997-11-25 06:05:25 +08:00
}
}