⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gvceps.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Copyright (C) 1993-2003, Ghostgum Software Pty Ltd.  All rights reserved.
  
  This file is part of GSview.
   
  This program is distributed with NO WARRANTY OF ANY KIND.  No author
  or distributor accepts any responsibility for the consequences of using it,
  or for whether it serves any particular purpose or works at all, unless he
  or she says so in writing.  Refer to the GSview Licence (the "Licence") 
  for full details.
   
  Every copy of GSview must include a copy of the Licence, normally in a 
  plain ASCII text file named LICENCE.  The Licence grants you the right 
  to copy, modify and redistribute GSview, but only under certain conditions 
  described in the Licence.  Among other things, the Licence requires that 
  the copyright notice and this notice be preserved on all copies.
*/

/* gvceps.c */
/* EPS file manipulation module of PM and Windows GSview */

#ifdef EPSTOOL
#include "epstool.h"
#else	/* GSview */
#include "gvc.h"
#endif

PSBBOX bbox;
DWORD get_dword(unsigned char *buf);
WORD get_word(unsigned char *buf);

#define tiff_long(val, f) write_dword(val, f)
#define tiff_short(val, f) write_word_as_dword(val, f)
#define tiff_word(val, f) write_word(val, f)

void write_dword(DWORD val, FILE *f);
void write_word_as_dword(WORD val, FILE *f);
void write_word(WORD val, FILE *f);

void write_doseps_header(struct eps_header_s *peps_header, FILE *outfile);
void copy_bbox_header(FILE *f);
void copy_trailer_without_bbox(FILE *f);
int scan_dib(PREBMAP *ppbmap, unsigned char *pbitmap);
void shift_preview(unsigned char *preview, int bwidth, int offset);
void scan_bbox(PREBMAP *pprebmap, PSBBOX *psbbox);
void get_dib_line(BYTE *line, unsigned char *preview, int width, int bitcount);
BYTE * get_dib_bits(unsigned char *pbitmap);
void make_bmp_info(LPBITMAP2 newpbm, PREBMAP *ppbmap, unsigned char *pbitmap);
int packbits(BYTE *comp, BYTE *raw, int length);
int write_tiff(FILE *f, unsigned char *pbitmap, BOOL tiff4, BOOL use_packbits, 
    BOOL calc_bbox);
int write_interchange(FILE *f, unsigned char *pbitmap, BOOL calc_bbox);


void 
ps_copy(FILE *outfile, GFile *infile, long begin, long end)
{
    char *buf;
    int count;
    buf = (char *)malloc(COPY_BUF_SIZE);
    if (buf == (char *)NULL)
	return;
    if (begin >= 0)
	gfile_seek(infile, begin, gfile_begin);
    begin = gfile_get_position(infile);
    while (begin < end) {
        count = min(end-begin, COPY_BUF_SIZE);
	if ((count = gfile_read(infile, buf, count)) > 0) {
	    fwrite(buf, 1, count, outfile);
	    begin += count;
	}
	else
	    begin = end;	/* EOF or error */
    }
    free(buf);
}

/* Like fgets, but allows any combination of EOL characters
 * and returns the count of bytes, not the string pointer
 */
int ps_fgets(char *s, int n, GFile *stream)
{
    char ch;
    int not_eof = 0;
    char *p = s;
    int count = 0;	/* bytes written to buffer */
    /* copy until first EOL character */
    while ( (count < n) &&  ((not_eof = gfile_read(stream, &ch, 1)) != 0)
	&& (ch != '\r') && (ch != '\n') ) {
	*p++ = (char)ch;
	count++;
    }

    if ((count < n) && not_eof) {
        /* check for extra EOL characters */
	if (ch == '\r') {
	    *p++ = (char)ch;
	    count++;
	    /* check if MS-DOS \r\n is being used */
	    if ((count < n) && ((not_eof = gfile_read(stream, &ch, 1)) != 0)) {
		if (ch == '\n') {
		    /* Yes, MS-DOS */
		    *p++ = (char)ch;
		    count++;
		}
		else {
		    /* No, Macintosh */
		    gfile_seek(stream, -1, gfile_current);
		}
	    }
	}
	else {
	    /* must have been '\n' */
	    *p++ = (char)ch;
	    count++;
	}
    }
    if (count < n)
	*p = '\0';

    if ( (!not_eof) && (p == s) )
	return 0;
    return count;
}


/* Copy DSC until a particular comment is found */
/* Do not copy the comment */
/* Stop if file offset exceeds end */
/* Assume that end does not occur in the middle of a line */
/* return TRUE if comment found, FALSE if not found */
BOOL ps_copy_find(FILE *outfile, GFile *infile, long end, 
	char *s, int n, const char *comment)
{
    int count;
    while ((gfile_get_position(infile) < end) && 
	((count = ps_fgets(s, n-1, infile))!=0)) {
	s[n-1] = '\0';
	if (strncmp(s, comment, strlen(comment)) == 0)
	    return TRUE;
	fwrite(s, 1, count, outfile);
    }
    return FALSE;
}


#ifndef EPSTOOL
/* At present only allows bounding box to be specified */
void
ps_to_eps(void)
{
char output[MAXSTR];
FILE *f;
char *buffer;
UINT count;
FILE *infile;
time_t t;
char *now;
char text[DSC_LINE_LENGTH];
long here;
CDSC *dsc = psfile.dsc;

	if (!pstoeps_warn()) {
	    nHelpTopic = IDS_TOPICPSTOEPS;
	    get_help();
	    return;
	}

	if ((gsdll.state != GS_PAGE) && (gsdll.state != GS_IDLE)) {
	    gserror(IDS_EPSNOBBOX, NULL, MB_ICONEXCLAMATION, SOUND_ERROR);
	    return;
	}

	if ((dsc != (CDSC *)NULL) && (dsc->page_count > 1)) {
	    gserror(IDS_EPSONEPAGE, NULL, MB_ICONEXCLAMATION, SOUND_ERROR);
	    return;
	}
	if (dsc == (CDSC *)NULL) {
	    TCHAR mess[MAXSTR];
	    load_string(IDS_EPSQPAGES, mess, sizeof(mess));
	    if (message_box(mess, MB_YESNO | MB_ICONQUESTION) != IDYES)
		return;
	}

	if (option.auto_bbox) {
	    unsigned char *pbitmap;
	    PREBMAP prebmap;
	    PSBBOX devbbox;	/* in pixel units */
	    if (option.orientation != IDM_PORTRAIT) {
		gserror(IDS_MUSTUSEPORTRAIT, 0, MB_ICONEXCLAMATION, 0); 
		return;
	    }
	    image_lock(view.img);
	    if ( (pbitmap = (unsigned char *)get_bitmap()) 
		== (unsigned char *)NULL) {
		    image_unlock(view.img);
		play_sound(SOUND_ERROR);
		return;
	    }
	    if (scan_dib(&prebmap, pbitmap))
	 	return;
	    devbbox.valid = FALSE;
	    bbox.valid = FALSE;
	    scan_bbox(&prebmap, &devbbox);
	    release_bitmap();
	    image_unlock(view.img);

	    if (devbbox.valid) {
		bbox.llx = (int)(devbbox.llx / option.xdpi * 72 - 0.5);
		bbox.lly = (int)(devbbox.lly / option.ydpi * 72 - 0.5);
		bbox.urx = (int)(devbbox.urx / option.xdpi * 72 + 1.5);
		bbox.ury = (int)(devbbox.ury / option.ydpi * 72 + 1.5);
		if (display.epsf_clipped) {
		    /* correct for clipped page */
		    int xoffset = 0;
		    int yoffset = 0;
		    if (dsc->bbox != (CDSCBBOX *)NULL) {
			xoffset = dsc->bbox->llx;
			yoffset = dsc->bbox->lly;
		    }
		    bbox.llx += xoffset;
		    bbox.lly += yoffset;
		    bbox.urx += xoffset;
		    bbox.ury += yoffset;
		}
		bbox.valid = TRUE;
	    }
	    if (!bbox.valid) {
		play_sound(SOUND_ERROR);
		return;
	    }
	}
	else {
	    if (!get_bbox()) {
		play_sound(SOUND_ERROR);
		return;
	    }
	}

	output[0] = '\0';
	if (!get_filename(output, TRUE, FILTER_EPS, 0, IDS_TOPICPSTOEPS))
	    return;

	if ((f = fopen(output, "wb")) == (FILE *)NULL) {
	    play_sound(SOUND_ERROR);
	    return;
	}

	if (dsc == (CDSC *)NULL) {
 	    char appname[MAXSTR];
	    convert_widechar(appname, szAppName, sizeof(appname)-1);
	    info_wait(IDS_WAITWRITE);
	    fputs("%!PS-Adobe-3.0 EPSF-3.0\r\n",f);
	    /* if this is not a single page document then gsview has just lied */
	    fprintf(f, "%%%%BoundingBox: %u %u %u %u\r\n",
		bbox.llx,bbox.lly,bbox.urx,bbox.ury);
	    fprintf(f,"%%%%Title: %s\r\n",psfile.name);
	    fprintf(f,"%%%%Creator: %s from %s\r\n",appname,psfile.name);
	    t = time(NULL);
	    now = ctime(&t);
	    now[strlen(now)-1] = '\0';	/* remove trailing \n */
	    fprintf(f,"%%%%CreationDate: %s\r\n",now);
	    fputs("%%Pages: 1\r\n",f);
	    fputs("%%EndComments\r\n",f);

	    fputs("%%Page: 1 1\r\n",f);
	    fprintf(f,"%%%%BeginDocument: %s\r\n",psfile.name);

	    /* create buffer for PS file copy */
	    buffer = (char *)malloc(COPY_BUF_SIZE);
	    if (buffer == (char *)NULL) {
	        play_sound(SOUND_ERROR);
	        fclose(f);
		unlink(output);
	        return;
	    }

	    infile = fopen(psfile_name(&psfile), "rb");
	    if (infile == (FILE *)NULL) {
	        play_sound(SOUND_ERROR);
	        fclose(f);
		unlink(output);
	        return;
	    }

            while ( (count = fread(buffer, 1, COPY_BUF_SIZE, infile)) != 0 ) {
	        fwrite(buffer, 1, count, f);
	    }
	    free(buffer);
	    fclose(infile);

	    fputs("\r\n%%EndDocument\r\n",f);
	    fputs("%%Trailer\r\n",f);
	    fclose(f);
	    info_wait(IDS_NOWAIT);
	}
	else {
	    /* document already has DSC comments */
	    info_wait(IDS_WAITWRITE);
	    gfile_seek(psfile.file, dsc->begincomments, gfile_begin);
	    ps_fgets(text, sizeof(text), psfile.file);
	    if (dsc->epsf)
	        fputs(text,f);
	    else
	        fputs("%!PS-Adobe-3.0 EPSF-3.0\r\n",f);
	    if (dsc->bbox != (CDSCBBOX *)NULL) {
		ps_copy_find(f, psfile.file, dsc->endcomments,
		    text, sizeof(text), "%%BoundingBox:");
	    }
	    fprintf(f, "%%%%BoundingBox: %d %d %d %d\r\n",
		bbox.llx, bbox.lly, bbox.urx, bbox.ury);
	    here = gfile_get_position(psfile.file);
	    ps_copy(f, psfile.file, here, dsc->endcomments);
	    ps_copy(f, psfile.file, dsc->begindefaults, dsc->enddefaults);
	    ps_copy(f, psfile.file, dsc->beginprolog, dsc->endprolog);
	    ps_copy(f, psfile.file, dsc->beginsetup, dsc->endsetup);
	    if (dsc->page_count)
	        ps_copy(f, psfile.file, dsc->page[0].begin, dsc->page[0].end);
	    copy_trailer_without_bbox(f);
	    fclose(f);
	    info_wait(IDS_NOWAIT);
	}
}
#endif


typedef struct tagWINRECT {
	WORD	left;
	WORD	top;
	WORD	right;
	WORD	bottom;
} WINRECT;

typedef struct {
    DWORD	key;
    WORD 	hmf;
    WINRECT 	bbox;
    WORD	inch;
    DWORD	reserved;
    WORD	checksum;
} METAFILEHEADER;

void
write_doseps_header(struct eps_header_s *peps_header, FILE *outfile)
{
    fputc(peps_header->id[0], outfile);
    fputc(peps_header->id[1], outfile);
    fputc(peps_header->id[2], outfile);
    fputc(peps_header->id[3], outfile);
    write_dword(peps_header->ps_begin, outfile);
    write_dword(peps_header->ps_length, outfile);
    write_dword(peps_header->mf_begin, outfile);
    write_dword(peps_header->mf_length, outfile);
    write_dword(peps_header->tiff_begin, outfile);
    write_dword(peps_header->tiff_length, outfile);
    write_word(peps_header->checksum, outfile);
}

/* extract EPS or TIFF or WMF file from DOS EPS file */
void 
extract_doseps(int command)
{
unsigned long pos;
unsigned long len;
unsigned int count;
char *buffer;
FILE* epsfile;
BOOL is_meta = TRUE;
char outname[MAXSTR];
FILE *outfile;
DWORD key;
#ifndef EPSTOOL
int filter;
#endif
CDSC *dsc = psfile.dsc;
	if ((dsc == (CDSC *)NULL) || (dsc->doseps == (CDSCDOSEPS *)NULL)) {
	    gserror(IDS_NOPREVIEW, NULL, MB_ICONEXCLAMATION, SOUND_ERROR);
	    return;
	}
	epsfile = fopen(psfile_name(&psfile),"rb");
	pos = dsc->doseps->ps_begin;
	len = dsc->doseps->ps_length;
	if (command == IDM_EXTRACTPRE) {
	    pos = dsc->doseps->wmf_begin;
	    len = dsc->doseps->wmf_length;
	    if (pos == 0L) {
	        pos = dsc->doseps->tiff_begin;
	        len = dsc->doseps->tiff_length;
	        is_meta = FALSE;
	    }
	}
	if (pos == 0L) {
	    fclose(epsfile);
	    gserror(IDS_NOPREVIEW, NULL, MB_ICONEXCLAMATION, SOUND_ERROR);
	    return;
	}
	fseek(epsfile, pos, SEEK_SET);	/* seek to section to extract */


#ifdef EPSTOOL
	/* assume outname already exists */
	strncpy(outname, oname, MAXSTR-1);
	if (*outname!='\0')
	    outfile = fopen(outname,"wb");
	else
	    outfile = stdout;
#else
	/* create postscript or preview file */
	outname[0] = '\0';
	if (command == IDM_EXTRACTPRE) {
	    if (is_meta)
	        filter = FILTER_WMF;
	    else
	        filter = FILTER_TIFF;
	}
	else
	    filter = FILTER_PS;
	if (!get_filename(outname, TRUE, filter, 0, IDS_TOPICPREVIEW)) {
	    fclose(epsfile);
	    return;
	}
	outfile = fopen(outname, "wb");
#endif
	if (outfile == (FILE *)NULL) {
	    play_sound(SOUND_ERROR);
	    fclose(epsfile);
	    return;
	}
	
	/* create buffer for file copy */
	buffer = (char *)malloc(COPY_BUF_SIZE);
	if (buffer == (char *)NULL) {
	    play_sound(SOUND_ERROR);
	    fclose(epsfile);
	    if (*outname!='\0')
	        fclose(outfile);
	    return;
	}

	if ((command == IDM_EXTRACTPRE) && is_meta) {
	    /* check if metafile already contains header */
	    char keybuf[4];
	    DWORD doseps_key = 0x9ac6cdd7UL;
	    fread(keybuf, 1, 4, epsfile);
	    key = keybuf[0] + (keybuf[1]<<8) + 
	          (keybuf[2]<<16) + (keybuf[3]<<24);
	    fseek(epsfile, pos, SEEK_SET);	/* seek to section to extract */
	    if ( key != doseps_key ) {
	        /* write placeable Windows Metafile header */
	        METAFILEHEADER mfh;
	        int i, temp;
	        unsigned short *pw;
	        mfh.key = doseps_key;
	        mfh.hmf = 0;
		/* guess the location - this might be wrong */
	        mfh.bbox.left = 0;
	        mfh.bbox.top = 0;
		if (dsc->bbox != (CDSCBBOX *)NULL) {
		    temp = (dsc->bbox->urx - dsc->bbox->llx);
		    /* double transfer to avoid GCC Solaris bug */
		    mfh.bbox.right = (WORD)temp;	
		    mfh.bbox.bottom = (WORD)(dsc->bbox->ury - dsc->bbox->lly);
		    temp = (dsc->bbox->ury - dsc->bbox->lly);
		    mfh.bbox.bottom = (WORD)temp;
		}
	  	else {
		    /* bbox missing, assume A4 */
		    mfh.bbox.right = 595;
		    mfh.bbox.bottom = 842;
		}
	        mfh.inch = 72;	/* PostScript points */
	        mfh.reserved = 0L;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -