243 lines · 7.1 KB · Text
RawDownload
%    Copyright (C) 1989, 1996, 2002 Aladdin Enterprises.  All rights reserved.% % This software is provided AS-IS with no warranty, either express or% implied.% % This software is distributed under license and may not be copied,% modified or distributed except as expressly authorized under the terms% of the license contained in the file LICENSE in this distribution.% % For more information about licensing, please refer to% http://www.ghostscript.com/licensing/. For information on% commercial licensing, go to http://www.artifex.com/licensing/ or% contact Artifex Software, Inc., 101 Lucas Valley Road #110,% San Rafael, CA  94903, U.S.A., +1(415)492-9861. % $Id: gs_epsf.ps,v 1.15 2005/08/30 23:26:49 alexcher Exp $% Allow the interpreter to encapsulate EPS files, to recognize MS-DOS % EPSF file headers, and skip to the PostScript section of the file. % Encapsulate EPS files and optionally resize page or rescale image.% To display an EPS file cropped to the bounding box:%  gs -dEPSCrop file.eps% To display an EPS file scaled to fit the page:%  gs -dEPSFitPage file.eps% To display a file without EPS encapsulation:%  gs -dNOEPS file.ps % When starting to process an EPS file, state is 0.% After %%BoundingBox processed, state is 1 if OK or 2 if cropped.% After %%HiResBoundingBox processed, state is 3 if OK or 4 if cropped.% After %%EndComments processed, state is 5./EPSBoundingBoxState 5 def/EPSBoundingBoxSetState {  //systemdict /EPSBoundingBoxState 3 -1 roll .forceput} .bind odef % .forceput must be bound and hidden % Parse 4 numbers for a bounding box/EPSBoundingBoxParse { % (llx lly urx ury) -- llx lly urx ury true OR false    mark exch    token {exch token {exch token {exch token {exch pop} if} if} if} if    counttomark    4 eq {      5 -1 roll pop % remove mark      true    } {      cleartomark false    } ifelse} bind def % Rescale and translate to fit the BoundingBox on the page/EPSBoundingBoxFitPage { % llx lly urx ury --  EPSDEBUG { (gs_epsf.ps: Rescaling EPS to fit page\n) print flush } if  clippath pathbbox newpath  % translate to new origin at lower left of clippath  3 index 3 index translate  % calculate scale to fit smaller of width or height  exch 4 -1 roll sub 3 1 roll exch sub   4 2 roll 5 index 5 index 4 2 roll  exch 4 -1 roll sub 3 1 roll exch sub   4 2 roll  exch 4 -1 roll div 3 1 roll exch div  1 index 1 index lt {pop}{exch pop} ifelse  dup scale  % translate to EPS -llx,-lly  exch neg exch neg translate} bind def % Crop the page to the BoundingBox/EPSBoundingBoxCrop { % llx lly urx ury --  EPSDEBUG {     (gs_epsf.ps: Setting pagesize from EPS bounding box\n) print flush   } if  exch 3 index sub exch 2 index sub % stack: llx lly urx-llx ury-lly  << /PageSize [ 5 -2 roll ] >> setpagedevice  neg exch neg exch translate} bind def  /EPSBoundingBoxProcess { % (llx lly urx ury) state --  //systemdict /EPSBoundingBoxState get 1 index lt {    exch EPSBoundingBoxParse     {      //systemdict /EPSCrop known {        EPSBoundingBoxCrop      } {        //systemdict /EPSFitPage known {          EPSBoundingBoxFitPage	} {	  % Warn if some of the EPS file will be clipped	  clippath pathbbox newpath	  { % context for exit	    5 -1 roll lt { 6 { pop } repeat true exit } if	    4 -1 roll lt { 4 { pop } repeat true exit } if	    3 -1 roll gt { 2 { pop } repeat true exit } if	    exch gt { true exit } if	    false exit	  } loop	  QUIET not and /EPSBoundingBoxState .systemvar 1 and 1 eq and {	    (\n   **** Warning: Some of the BoundingBox for the EPS file will be clipped.) =	    (                 Use -dEPSCrop or -dEPSFitPage to avoid clipping.\n) =	    flush            1 add          } if	} ifelse      } ifelse      EPSBoundingBoxSetState    } {      pop % state    } ifelse  } {    pop pop  } ifelse} bind def /ProcessEPSComment { % file comment --  file comment  //systemdict /EPSBoundingBoxState get 3 lt {    dup    (%%EndComments) anchorsearch {      pop pop      % ignore any following bounding boxes      5 EPSBoundingBoxSetState    } {      (%%BoundingBox:) anchorsearch {	pop 	EPSDEBUG { (gs_epsf.ps: found %%BoundingBox\n) print flush } if	1 EPSBoundingBoxProcess      } {	(%%HiResBoundingBox:) anchorsearch {	  pop 	  EPSDEBUG { (gs_epsf.ps: found %%HiResBoundingBox\n) print flush } if	3 EPSBoundingBoxProcess	} { 	  pop % Not interested in this DSC comment	} ifelse      } ifelse    } ifelse  } if} bind def % Install EPS handler for DSC comments, which we do later/EPSBoundingBoxInit {  systemdict /NOEPS known not {    % Merge ProcessEPSComment with existing handler    /ProcessEPSComment load /exec load    currentuserparams /ProcessDSCComment get     dup null eq {pop {pop pop}} if /exec load    4 array astore cvx readonly    << /ProcessDSCComment 3 -1 roll >> setuserparams  } if} bind def /.runNoEPS /run load def /.runEPS { % file OR string --  /runEPS_save save def  /runEPS_dict_count countdictstack def  /runEPS_op_count count 2 sub def  /runEPS_page_count currentpagedevice /PageCount get def   0 EPSBoundingBoxSetState  .runNoEPS  currentpagedevice /PageCount get runEPS_page_count sub 0 eq   { /showpage load exec } if  count runEPS_op_count sub {pop} repeat  countdictstack runEPS_dict_count sub {end} repeat  runEPS_save restore} bind def /run { % file OR string --  dup type /filetype ne { (r) file } if  dup (%!PS-Adobe-) .peekstring {    (%!PS-Adobe-) eq {      dup (%!PS-Adobe-X.X EPSF-X.X) .peekstring {      (EPSF) search {        pop pop pop        EPSDEBUG {(runEPS: Found EPS\n) print flush} if        systemdict /NOEPS known {          cvx .runNoEPS        } {          cvx .runEPS        } ifelse      } {        EPSDEBUG {(runEPS: Normal DSC\n) print flush} if        pop          cvx .runNoEPS       } ifelse      } {        EPSDEBUG {(runEPS: Short DSC\n) print flush} if      pop        cvx .runNoEPS      } ifelse    } {      EPSDEBUG {(runEPS: Not DSC\n) print flush} if      cvx .runNoEPS    } ifelse  } {    EPSDEBUG {(runEPS: Short non-DSC\n) print flush} if    pop    cvx .runNoEPS  } ifelse} bind odef  % Handle DOS EPS files. /.runnoepsf /run load def/.epsfheader <C5D0D3C6> def/run { dup type /filetype ne { (r) file } if		% Check for MS-DOS EPSF file (see Red Book p. 729). dup (    ) .peekstring   { .epsfheader eq { dup (    ) readstring exch pop } { false } ifelse }  { pop false } ifelse		% Stack: file true/false    {		% This block is executed if the file is MS-DOS EPSF.		% Build up the little-endian byte offset and length.      2	{ 1 0 4	   { 2 index read not { pop exit } if % if EOF, let error happen	     2 index mul add exch 256 mul exch	   }	  repeat exch pop exch	}      repeat		% Stack: offset length file		% Use flushfile to skip quickly to the start of the		% PostScript section.      dup 4 -1 roll 12 sub () /SubFileDecode filter flushfile		% Now interpret the PostScript.      exch () /SubFileDecode filter cvx run    }    { .runnoepsf    }   ifelse } odef % rebind .runstdin to use redefined runuserdict begin/.runstdin {  { (%stdin) run } execute0} bind defend