📄 gvceps.c
字号:
fclose(epifile);
release_bitmap();
if (code)
unlink(epiname);
return code;
}
/* scan bitmap and return bbox measured in pixels */
void
scan_bbox(PREBMAP *pprebmap, PSBBOX *devbbox)
{
unsigned char *preview;
BYTE *line;
int bwidth = ((pprebmap->width + 7) & ~7) >> 3; /* byte width with 1 bit/pixel */
int i, j, k, l;
int x;
BYTE ch;
BYTE *chline;
unsigned char omask;
devbbox->llx = pprebmap->width;
devbbox->lly = pprebmap->height;
devbbox->urx = devbbox->ury = 0;
devbbox->valid = FALSE;
preview = (unsigned char *) malloc(bwidth);
memset(preview,0xff,bwidth);
if (pprebmap->bits) {
if (pprebmap->topleft)
line = (BYTE *)pprebmap->bits + ((long)pprebmap->bytewidth * (pprebmap->height-1));
else
line = (BYTE *)pprebmap->bits;
}
else {
devbbox->llx = 0;
devbbox->lly = 0;
devbbox->urx = pprebmap->width;
devbbox->ury = pprebmap->height;
devbbox->valid = FALSE;
return;
}
/* process each line of bitmap */
for (i = 0; i < pprebmap->height; i++) {
/* get 1bit/pixel line, 0=black, 1=white */
get_dib_line(line, preview, pprebmap->width, pprebmap->depth);
chline = preview;
ch = 0;
for (j=0; j<bwidth; j++)
ch |= (BYTE)(~(*chline++)); /* check for black pixels */
if (ch) {
/* adjust y coordinates of bounding box */
if (i < devbbox->lly)
devbbox->lly = i;
if (i+1 > devbbox->ury)
devbbox->ury = i+1;
/* scan for x coordinates of black pixels */
chline = preview;
for (k=0; k<bwidth; k++) {
if (~(*chline) & 0xff) { /* a pixel is black */
omask = 0x80;
for (l=0; l<8; l++) {
if ( ~*chline & omask ) {
x = k*8 + l;
if (x < devbbox->llx)
devbbox->llx = x;
if (x+1 > devbbox->urx)
devbbox->urx = x+1;
}
omask >>= 1;
}
}
chline++;
}
}
if (pprebmap->bits) {
if (pprebmap->topleft)
line -= pprebmap->bytewidth;
else
line += pprebmap->bytewidth;
}
}
free(preview);
if ( (devbbox->lly < devbbox->ury) && (devbbox->llx < devbbox->urx) )
devbbox->valid = TRUE;
if (debug)
{ char buf[256];
sprintf(buf, "scan_bbox=[%d %d %d %d] in pixels\n", devbbox->llx, devbbox->lly, devbbox->urx, devbbox->ury);
gs_addmess(buf);
}
}
/* shift preview by offset bits to the left */
/* width is in bytes */
/* fill exposed bits with 1's */
void
shift_preview(unsigned char *preview, int bwidth, int offset)
{
int bitoffset;
int byteoffset;
int newwidth;
int shifter;
int i;
if (offset == 0)
return;
byteoffset = offset / 8;
newwidth = bwidth - byteoffset;
/* first remove byte offset */
memmove(preview, preview+byteoffset, newwidth);
memset(preview+newwidth, 0xff, bwidth-newwidth);
/* next remove bit offset */
bitoffset = offset - byteoffset*8;
if (bitoffset==0)
return;
bitoffset = 8 - bitoffset;
for (i=0; i<newwidth; i++) {
shifter = preview[i] << 8;
if (i==newwidth-1)
shifter += 0xff; /* can't access preview[bwidth] */
else
shifter += preview[i+1];
preview[i] = (unsigned char)(shifter>>bitoffset);
}
}
/* Copy the header to file f */
/* change bbox line if present, or add bbox line */
void
copy_bbox_header(FILE *f)
{
char text[DSC_LINE_LENGTH+1];
BOOL bbox_written = FALSE;
long position;
CDSC *dsc = psfile.dsc;
gfile_seek(psfile.file, dsc->begincomments, gfile_begin);
if (dsc->bbox != (CDSCBBOX *)NULL) {
while ( ps_copy_find(f, psfile.file, dsc->endcomments,
text, sizeof(text), "%%BoundingBox:") ) {
if (!bbox_written) {
fprintf(f, "%%%%BoundingBox: %d %d %d %d\r\n",
bbox.llx, bbox.lly, bbox.urx, bbox.ury);
bbox_written = TRUE;
}
}
}
else {
ps_fgets(text, sizeof(text), psfile.file);
fputs(text,f);
fprintf(f, "%%%%BoundingBox: %d %d %d %d\r\n",
bbox.llx, bbox.lly, bbox.urx, bbox.ury);
position = gfile_get_position(psfile.file);
ps_copy(f, psfile.file, position, dsc->endcomments);
}
}
/* Copy the trailer to file f, removing bbox line if present */
void
copy_trailer_without_bbox(FILE *f)
{
char text[DSC_LINE_LENGTH+1];
CDSC *dsc = psfile.dsc;
gfile_seek(psfile.file, dsc->begintrailer, gfile_begin);
while ( ps_copy_find(f, psfile.file, dsc->endtrailer,
text, sizeof(text), "%%BoundingBox:") ) {
/* do NOT copy the bounding box */
}
}
/* make a PC EPS file */
/* from a PS file and a user supplied preview */
/* preview may be WMF or TIFF */
/* returns 0 on success */
int
make_eps_user(void)
{
char epsname[MAXSTR];
char *buffer;
unsigned int count;
FILE *epsfile;
FILE *preview_file;
char preview_name[MAXSTR];
unsigned long preview_length;
#if defined(__EMX__) || defined (_MSC_VER)
#pragma pack(1)
#endif
struct eps_header_s eps_header;
#if defined(__EMX__) || defined (_MSC_VER)
#pragma pack()
#endif
int type = 0;
#define TIFF 1
#define WMF 2
char id[4];
CDSC *dsc = psfile.dsc;
long end;
/* get user supplied preview */
#ifdef EPSTOOL
strncpy(preview_name, upname, MAXSTR-1);
#else
preview_name[0] = '\0';
if (!get_filename(preview_name, FALSE, FILTER_ALL, IDS_EPSUSERTITLE, IDS_TOPICPREVIEW))
return 1; /* failure */
#endif
/* open preview, determine length and type */
preview_file = fopen(preview_name, "rb");
if (preview_file == (FILE *)NULL) {
play_sound(SOUND_ERROR);
return 1;
}
id[0] = (char)fgetc(preview_file);
id[1] = (char)fgetc(preview_file);
id[2] = (char)fgetc(preview_file);
id[3] = (char)fgetc(preview_file);
fseek(preview_file, 0, SEEK_END);
preview_length = ftell(preview_file);
fseek(preview_file, 0, SEEK_SET);
if ((id[0] == 'I') && (id[1] == 'I'))
type = TIFF;
if ((id[0] == 'M') && (id[1] == 'M'))
type = TIFF;
if ((id[0] == (char)0x01) && (id[1] == (char)0x00) && (id[2] == (char)0x09) && (id[3] == (char)0x00))
type = WMF;
if ((id[0] == (char)0xd7) && (id[1] == (char)0xcd) && (id[2] == (char)0xc6) && (id[3] == (char)0x9a)) {
type = WMF;
preview_length -= 22; /* skip over placeable metafile header */
fseek(preview_file, 22, SEEK_SET);
}
if (type == 0) {
gserror(IDS_EPSUSERINVALID, NULL, MB_ICONEXCLAMATION, SOUND_ERROR);
fclose(preview_file);
return 1;
}
#ifdef EPSTOOL
strncpy(epsname, oname, MAXSTR-1);
if (*epsname!='\0')
epsfile = fopen(epsname,"wb");
else
epsfile = stdout;
#else
/* create EPS file */
epsname[0] = '\0';
if (!get_filename(epsname, TRUE, FILTER_EPS, 0, IDS_TOPICPREVIEW)) {
fclose(preview_file);
return 1;
}
epsfile = fopen(epsname,"wb");
#endif
if (epsfile == (FILE *)NULL) {
play_sound(SOUND_ERROR);
fclose(preview_file);
return 1;
}
/* write DOS EPS binary header */
eps_header.id[0] = (char) 0xc5;
eps_header.id[1] = (char) 0xd0;
eps_header.id[2] = (char) 0xd3;
eps_header.id[3] = (char) 0xc6;
eps_header.ps_begin = EPS_HEADER_SIZE;
end = psfile.dsc->begincomments;
if (dsc->endcomments)
end = dsc->endcomments;
if (dsc->enddefaults)
end = dsc->enddefaults;
if (dsc->endprolog)
end = dsc->endprolog;
if (dsc->endsetup)
end = dsc->endsetup;
if (dsc->page_count && dsc->page[0].end)
end = dsc->page[0].end;
if (dsc->endtrailer)
end = dsc->endtrailer;
eps_header.ps_length = end - psfile.dsc->begincomments;
if (type == WMF) {
eps_header.mf_begin = eps_header.ps_begin + eps_header.ps_length;
eps_header.mf_length = preview_length;
eps_header.tiff_begin = 0;
eps_header.tiff_length = 0;
}
else {
eps_header.mf_begin = 0;
eps_header.mf_length = 0;
eps_header.tiff_begin = eps_header.ps_begin + eps_header.ps_length;
eps_header.tiff_length = preview_length;
}
eps_header.checksum = 0xffff;
write_doseps_header(&eps_header, epsfile);
ps_copy(epsfile, psfile.file, dsc->begincomments, dsc->endcomments);
ps_copy(epsfile, psfile.file, dsc->begindefaults, dsc->enddefaults);
ps_copy(epsfile, psfile.file, dsc->beginprolog, dsc->endprolog);
ps_copy(epsfile, psfile.file, dsc->beginsetup, dsc->endsetup);
if (dsc->page_count)
ps_copy(epsfile, psfile.file, dsc->page[0].begin, dsc->page[0].end);
ps_copy(epsfile, psfile.file, dsc->begintrailer, dsc->endtrailer);
/* copy preview file */
buffer = (char *)malloc(COPY_BUF_SIZE);
if (buffer == (char *)NULL) {
play_sound(SOUND_ERROR);
fclose(epsfile);
unlink(epsname);
fclose(preview_file);
return 1;
}
while ( (count = fread(buffer, 1, COPY_BUF_SIZE, preview_file)) != 0 )
fwrite(buffer, 1, count, epsfile);
free(buffer);
fclose(preview_file);
if (*epsname!='\0')
fclose(epsfile);
return 0; /* success */
#undef TIFF
#undef WMF
}
typedef struct tagMFH {
WORD type;
WORD headersize;
WORD version;
DWORD size;
WORD nobj;
DWORD maxrec;
WORD noparam;
} MFH;
int metafile_init(unsigned char *pbitmap, BOOL calc_bbox, PSBBOX *pdevbbox,
MFH* mf);
void write_bitmap_info(LPBITMAP2 pbmi, int palcount, FILE *f);
int write_metafile(FILE *f, unsigned char *pbitmap, PSBBOX *pdevbbox, MFH *mf);
/* A metafile object must not be larger than 64k */
/* Metafile bitmap object contains metafile header, */
/* bitmap header, palette and bitmap bits */
#define MAX_METAFILE_BITMAP 64000L /* max size of bitmap bits */
int
metafile_init(unsigned char *pbitmap, BOOL calc_bbox, PSBBOX *pdevbbox, MFH* mf)
{
PREBMAP prebmap;
int wx, wy;
int ny, nylast;
int complete, partial;
int bytewidth;
int palcount;
int code;
unsigned long size;
if (*pbitmap == 'P')
code = scan_pbmplus(&prebmap, pbitmap);
else {
code = scan_dib(&prebmap, pbitmap);
}
if (code)
return code;
if (calc_bbox) {
scan_bbox(&prebmap, pdevbbox);
if (pdevbbox->valid) {
/* copy to global bbox as if obtained by PS to EPS */
bbox.llx = (int)(pdevbbox->llx * 72.0 / option.xdpi - 0.5);
bbox.lly = (int)(pdevbbox->lly * 72.0 / option.ydpi - 0.5);
bbox.urx = (int)(pdevbbox->urx * 72.0 / option.xdpi + 1.5);
bbox.ury = (int)(pdevbbox->ury * 72.0 / option.ydpi + 1.5);
bbox.valid = TRUE;
}
}
else {
#ifdef EPSTOOL
pdevbbox->urx = prebmap.width;
pdevbbox->ury = prebmap.height;
pdevbbox->llx = pdevbbox->lly = 0;
#else
if (display.epsf_clipped || (psfile.dsc->bbox==(CDSCBBOX *)NULL)) {
/* copy all of display bitmap */
pdevbbox->urx = prebmap.width;
pdevbbox->ury = prebmap.height;
pdevbbox->llx = pdevbbox->lly = 0;
}
else {
/* copy only part of display bitmap */
pdevbbox->llx = (int)(psfile.dsc->bbox->llx * option.xdpi / 72.0);
pdevbbox->lly = (int)(psfile.dsc->bbox->lly * option.ydpi / 72.0);
pdevbbox->urx = (int)(psfile.dsc->bbox->urx * option.xdpi / 72.0 + 0.5);
pdevbbox->ury = (int)(psfile.dsc->bbox->ury * option.ydpi / 72.0 + 0.5);
#define LIMIT(z, limit) if (z < 0) z = 0; else if (z > limit) z = limit
LIMIT(pdevbbox->llx, prebmap.width);
LIMIT(pdevbbox->lly, prebmap.height);
LIMIT(pdevbbox->urx, prebmap.width);
LIMIT(pdevbbox->ury, prebmap.height);
#undef LIMIT
}
#endif
}
wx = pdevbbox->urx - pdevbbox->llx;
wy = pdevbbox->ury - pdevbbox->lly;
bytewidth = (( wx * prebmap.depth + 31) & ~31) >> 3;
ny = (int)(MAX_METAFILE_BITMAP / bytewidth);
if (prebmap.depth == 24)
palcount = 0;
else
palcount = 1<<prebmap.depth;
complete = wy / ny;
nylast = wy % ny;
partial = nylast ? 1 : 0;
mf->type = 1; /* metafile in file */
mf->headersize = 9; /* 9 WORDs */
mf->version = 0x300; /* Windows 3.0 */
mf->size = /* sizes in WORDs */
9UL + /* header */
5 + /* SetWindowOrg */
5; /* SetWindowExt */
/* complete StretchDIBits */
mf->size += 14*complete;
size = (40L + palcount*4L + (unsigned long)ny*(unsigned long)bytewidth)/2L;
mf->size += size * (unsigned long)complete;
/* partial StretchDIBits */
mf->size += 14*partial;
size = (40L + palcount*4L + (unsigned long)nylast*(unsigned long)bytewidth)/2L;
mf->size += size * (unsigned long)partial;
mf->size += 3; /* end marker */
mf->nobj = 0;
size = complete ?
(40L + palcount*4L + (unsigned long)ny*(unsigned long)bytewidth)/2L
: (40L + palcount*4L + (unsigned long)nylast*(unsigned long)bytewidth)/2L;
mf->maxrec = 14L + size;
mf->noparam = 0;
return 0;
}
/* WARNING: pbmi might not be packed.
* pbmi->biSize=40 if packed, larger otherwise.
* The palette will be at offset pbmi->biSize, not BITMAP2_LENGTH
*/
void
write_bitmap_info(LPBITMAP2 pbmi, int palcount, FILE *f)
{
int i;
unsigned char *prgb;
/* write bitmap info */
write_dword(BITMAP2_LENGTH, f);
write_dword(pbmi->biWidth, f);
write_dword(pbmi->biHeight, f);
write_word(pbmi->biPlanes, f);
write_word(pbmi->biBitCount, f);
write_dword(pbmi->biCompression, f);
write_dword(pbmi->biSizeImage, f);
write_d
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -