Академический Документы
Профессиональный Документы
Культура Документы
%
% 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.
end % pdfdict
userdict begin
/defaultfontname /Times-Roman def
% Make sure the registered encodings are loaded, so we don't run the risk
% that some of the indices for their names will overflow the packed
% representation. (Yes, this is a hack.)
SymbolEncoding pop
DingbatsEncoding pop
/runpdfend {
Repaired { printrepaired } if
currentdict pdfclose
end % temporary dict
end % pdfdict
end % GS_PDF_ProcSet
PDFTopSave restore
end % userdict
} bind def
end % userdict
pdfdict begin
/traileropdict mark
(<<) cvn { mark } bind
(>>) cvn { { .dicttomark } stopped {
( **** File has unbalanced >> in trailer.\n) pdfformaterror
} if } bind
([) cvn { mark } bind % ditto
(]) cvn dup load
% /true true % see .pdfexectoken in pdf_base.ps
% /false false % ibid.
% /null null % ibid.
/R { /resolveR cvx 3 packedarray cvx } bind % see Objects below
/startxref /exit load
.dicttomark readonly def
% This dicitonary is used to read the xref dictionary. It should work for
% reading any dictionary. dictlevelcount must contain 0.
/xrefopdict mark
(<<) cvn { /dictlevelcount dictlevelcount 1 add def mark } bind
(>>) cvn { .dicttomark /dictlevelcount dictlevelcount 1 sub def
dictlevelcount 0 eq { exit} if } bind
([) cvn { mark } bind % ditto
(]) cvn dup load
% /true true % see .pdfexectoken in pdf_base.ps
% /false false % ibid.
% /null null % ibid.
/R { /resolveR cvx 3 packedarray cvx } bind % see Objects below
.dicttomark readonly def
% Open a PDF file and read the header, trailer, and cross-reference.
/pdfopen { % <file> pdfopen <dict>
% Color space substitution in PDF is handled somewhat differently
% than in PostScript. A given device color space will be substituted
% if the corresponding "Default..." entry exists in the Page's
% Resource dictionary (which might be inhereted); there is no
% UseCIEColor to enable/disable color mapping.
%
% This behavior is achieved by always setting UseCIEColor to true
% in the page device dictionary. If the value of this parameter was
% originally false (i.e.: the output device does not perform color
% space substitution by default), the instances DefaultGray,
% DefaultRGB, and DefaultCMYK of the (local) ColorSpace category
% are redefined to be DeviceGray, DeviceRGB, and DeviceCMYK,
% respectively. This is not done if UseCIEColor is true by default,
% as in that case color substitution is presumably desired even
% if the file does not request it.
currentpagedevice /UseCIEColor .knownget dup { pop } if not
{ .currentglobal false .setglobal
/DefaultGray { /DeviceGray } cvlit /ColorSpace defineresource pop
/DefaultRGB { /DeviceRGB } cvlit /ColorSpace defineresource pop
/DefaultCMYK { /DeviceCMYK } cvlit /ColorSpace defineresource pop
.setglobal
}
if
pdfopenfile begin
pdfopencache
.writepdfmarks {
% Copy bookmarks (outline) to the output.
Trailer /Root oget /Outlines knownoget {
/First knownoget {
{ dup writeoutline /Next knownoget not { exit } if } loop
} if
} if
} if % end .writepdfmarks
currentdict end
} bind def
% Verify that each entry in the xref table is pointing at an object with
% the correct object number and generation number.
/verify_xref % - verify_xref -
{ 1 1 Objects llength 1 sub % stack: 1 1 <number of objects - 1>
{ % Check if the object is free (i.e. not used). The values in
% Generations is the generation number plus 1. If the value in
% Generations is zero then the object is free.
Generations 1 index lget % Get the genration number
0 ne { % Skip if object number is free
ObjectStream 1 index lget % Check if object is in objectstream
0 eq { % We only check objects not in an objectstream
{ % Use stop context since we may get an error if object is invalid
dup Objects exch lget % Get the object location
PDFoffset add PDFfile exch setfileposition
true % Stack: <obj num> <true>
PDFfile token pop % Read object number from file
2 index eq { % Verify object number
PDFfile token pop % Read generation number from file
Generations 3 index % Get specified generaton number
lget 1 sub % Gen numbs are stored with 1 added.
eq { % Verify generation number
PDFfile token pop /obj eq { % Verify 'obj' text
pop false % We have valid object, do not rebuild
} if
} if
} if
} .internalstopped
{ true } if % If we stop then we need to rebuild
{
( **** Warning: File has an invalid xref entry: )
pdfformaterror
pdfstring cvs pdfformaterror
(. Rebuilding xref table.\n) pdfformaterror
search_objects
exit
} if % If the entry is invalid
} if % If not in an object stream
} if % If object entry is not free
pop % Remove object number
} for
} bind odef
/pdfopencache { % - pdfopencache -
% Create and initialize some caches.
/PageCount pdfpagecount def
/PageNumbers PageCount 65534 .min dict def
/PageIndex PageCount 65534 .min array def
} bind def
% Skip backward over the %%EOF at the end of the PDF file, and read
% the preceding startxref line. The PDF specification unambiguously
% requires that the %%EOF appear on a line by itself, and that the
% startxref and the following position value appear on separate lines;
% however, some applications (including, apparently, Acrobat Distiller
% on the Macintosh) may add up to 2K of garbage after the %%EOF, and some
% other applications also truncate the %%EOF to %%EO, and/or put the
% startxref and the following value on the same line.
% A file reported from Distiller 3.02b for AIX 4.1.1 has 2076 bytes
% of garbage. The tolerance is increased to 4K to cover future
% applications and bigger allocation units.
/findxref { % - findxref <xrefpos>
PDFfile dup dup 0 setfileposition bytesavailable
dup /PDFfilelen exch def
% Find the last %%EOF string (within 4096 bytes)
4096 sub PDFoffset .max
2 copy setfileposition
PDFfilelen exch sub string 1 index exch readstring pop {
(\015%%EO) search { % Adobe can handle truncated key string
pop pop % if found, keep searching 'post' string
} {
(\012%%EO) search
{ pop pop } { exit } ifelse % exit if neither string found
} ifelse
} loop
PDFfilelen exch length sub 4 sub PDFoffset .max exch 1 index setfileposition
% Stack: eofpos
% Check for whether this is, in fact, a valid PDF file.
dup PDFfilelen exch sub dup dup 7 gt exch 5 lt or {
pop true
} {
string PDFfile exch readstring pop
dup (%%EOF\n) eq exch dup (%%EOF\r) eq
exch dup (%%EOF\r\n) eq exch (%%EOF) eq or or or not
} ifelse {
( **** Warning: File has a corrupted %%EOF marker, or garbage after %%EOF.\n)
pdfformaterror
} if
PDFfile exch setfileposition
% Now read the startxref and xref start position.
prevline token not { null } if dup type /integertype eq {
exch pop cvi % xref start position
exch PDFfile exch setfileposition
prevline dup (startxref) linene {
% startxref not on a line by itself. We have found PDF from
% www.verypdf.com in which the startxref was on the same line as
% the end of trailer dictionary. Check for this. Note: This
% violates the spec.
dup (startxref) search {
% found startxref - print warning
pop pop pop % clear strings from search
( **** Warning: format of the startxref line in this file is invalid.\n)
pdfformaterror
} { % no startxref - we have a problem.
/findxref cvx /syntaxerror signalerror
} ifelse
} if
pop pop
} { % else, this file has 'startxref #####' format
(startxref) ne { /findxref cvx /syntaxerror signalerror } if
cvi % xref start position
( **** Warning: format of the startxref line in this file is invalid.\n)
pdfformaterror
exch PDFfile exch setfileposition
} ifelse
} bind def
/stderrfile (%stderr) (w) file def
/stderrprint { % <string> stderrprint -
//stderrfile dup 3 -1 roll writestring flushfile
} bind def
/pdfformaterror { % <string> pdfformaterror -
stderrprint
/Repaired true store
} bind def
/knownoget_safe
{ knownoget
} odef
/printProducer {
Trailer /Info { knownoget_safe } stopped { false } if {
/Producer knownoget not { null } if
} {
null
} ifelse
dup null eq {
pop
} {
( **** The file was produced by: \n **** >>>> ) stderrprint
% Handle a Unicode Producer.
(\376\377) anchorsearch {
pop dup length 2 idiv string 0 1 2 index length 1 sub {
% Stack: origstr newstr i
1 index exch 3 index 1 index 2 mul 1 add get put
} for exch pop
} if
stderrprint
( <<<<\n) stderrprint
} ifelse
} bind def
/printrepaired {
(\n **** This file had errors that were repaired or ignored.\n)
stderrprint
printProducer
( **** Please notify the author of the software that produced this\n)
stderrprint
( **** file that it does not conform to Adobe's published PDF\n)
stderrprint
( **** specification.\n\n)
stderrprint
} bind def
% Find the N'th page of the document by iterating through the Pages tree.
% The first page is numbered 1.
/pdffindpageref { % <int> pdffindpage <objref>
dup Trailer /Root oget /Pages get
{ % We should be able to tell when we reach a leaf
% by finding a Type unequal to /Pages. Unfortunately,
% some files distributed by Adobe lack the Type key
% in some of the Pages nodes! Instead, we check for Kids.
dup oforce /Kids knownoget not { exit } if
exch pop null
0 1 3 index length 1 sub {
2 index exch get
dup oforce dup /Kids known { /Count oget } { pop 1 } ifelse
% Stack: index kids null noderef count
dup 5 index ge { pop exch pop exit } if
5 -1 roll exch sub 4 1 roll pop
} for exch pop
% Stack: index null|noderef
dup null eq { pop pop 1 null exit } if
} loop
% Stack: index countleft noderef
1 index 1 ne { pop pop /pdffindpage cvx /rangecheck signalerror } if
exch pop
PageIndex 2 index 1 sub 65533 .min 2 index oforce put
PageNumbers 1 index oforce 3 index dup 65534 le
{ put }
{ pop pop pop } % don't store more than 65534 pagenumbers
ifelse
exch pop
} bind def
/pdffindpage { % <int> pdffindpage <pagedict>
pdffindpageref oforce
} bind def
% set up color space substitution (this must be inside the page save)
pdfshowpage_setcspacesub
.writepdfmarks {
1 index /CropBox pget dup {exch pop} if systemdict /UseCropBox known and {
1 index /CropBox pget pop
} {
1 index /MediaBox pget pop % There has to be a MediaBox
} ifelse
oforce_array
dup 0 get exch 1 get % [] tx ty
2 index 0 get 2 index sub 3 index exch 0 exch put
2 index 2 get 2 index sub 3 index exch 2 exch put
2 index 1 get 1 index sub 3 index exch 1 exch put
2 index 3 get 1 index sub 3 index exch 3 exch put
pop pop
} if % end .writepdfmarks
%
% <pagedict> pdfshowpage_setcspacesub <pagedict>
%
% Set up color space substitution for a page. Invocations of this procedure
% must be bracketed by the save/restore operation for the page, to avoid
% unintended effects on other pages.
%
% If any color space substitution is used, and the current color space is a
% device dependent color space, make sure the current color space is updated.
% There is an optimization in the setcolorspace pseudo-operator that does
% nothing if both the current and operand color spaces are the same. For
% PostScript this optimization is disabled if the UseCIEColor page device
% parameter is true. This is not the case for PDF, as performance suffers
% significantly on some PDF files if color spaces are set repeatedly. Hence,
% if color space substitution is to be used, and the current color space
% is a device dependent color space, we must make sure to "transition" the
% current color space.
%
/pdfshowpage_setcspacesub
{
false
{ /DefaultGray /DefaultRGB /DefaultCMYK }
{
dup 3 index /ColorSpace //rget exec
{ resolvecolorspace /ColorSpace defineresource pop }
{ pop }
ifelse
}
forall
end % pdfdict
.setglobal