📄 pdf_main.ps
字号:
% Copyright (C) 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
% Aladdin Ghostscript 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 Aladdin Ghostscript Free Public
% License (the "License") for full details.
%
% Every copy of Aladdin Ghostscript must include a copy of the License,
% normally in a plain ASCII text file named PUBLIC. The License grants you
% the right to copy, modify and redistribute Aladdin Ghostscript, but only
% under certain conditions described in the License. Among other things, the
% License requires that the copyright notice and this notice be preserved on
% all copies.
% $Id: pdf_main.ps $
% pdf_main.ps
% PDF file- and page-level operations.
/.setlanguagelevel where { pop 2 .setlanguagelevel } if
.currentglobal true .setglobal
/pdfdict where { pop } { /pdfdict 100 dict def } ifelse
pdfdict begin
% Patch in an obsolete variable used by some third-party software.
/#? false def
% For simplicity, we use a single interpretation dictionary for all
% PDF graphics execution, even though this is too liberal.
/pdfopdict mark
objopdict { } forall
drawopdict { } forall
/endstream { exit } bind
(%%EOF) cvn { exit } bind % for filters
% PDF 1.1 operators
/BX { /BXlevel BXlevel 1 add store } bind
/EX { /BXlevel BXlevel 1 sub store } bind
/PS { cvx exec } bind
% PDF 1.2 operators
/BMC { pop } bind
/BDC { pop pop } bind
/EMC { }
/MP { pop } bind
/DP { pop pop } bind
.dicttomark readonly def
% ======================== Main program ======================== %
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
% Redefine 'run' so it recognizes PDF files.
systemdict begin
/.runps /run load def
/runpdfstring 50 string def % length is arbitrary
/run
{ dup type /filetype ne { (r) file } if
dup read
{ dup (%) 0 get eq
{ pop dup //runpdfstring
% Some invalid files might have extra-long first lines....
{ { readline } .internalstopped not { pop pop exit } if
pop =string
}
loop
//runpdfstring (PDF-) anchorsearch
{ pop pop runpdf }
{ pop cvx .runexec }
ifelse
}
{ 2 copy unread pop .runps
}
ifelse
}
{ closefile
}
ifelse
} bind odef
/runpdf % <file> runpdf -
{ userdict begin
/Page# null def
/Page null def
/DSCPageCount 0 def
/PDFSave null def
GS_PDF_ProcSet begin
pdfdict begin
pdfopen begin
Trailer /Root oget /Pages oget /CropBox knownoget
{ mark /CropBox 3 -1 roll /PAGES pdfmark
}
if
/FirstPage where { pop FirstPage } { 1 } ifelse
1
/LastPage where { pop LastPage } { pdfpagecount } ifelse
QUIET not
{ (Processing pages ) print 2 index =only ( through ) print dup =only
(.\n) print flush
}
if
{ dup /Page# exch store
QUIET not { (Page ) print dup == flush } if
pdfgetpage pdfshowpage
} for
currentdict pdfclose
end % temporary dict
end % pdfdict
end % userdict
} bind def
end % systemdict
% Redefine the procedure that the C code uses for running piped input.
% It is OK to use { (%stdin) run } here, because a startjob cannot occur.
/.runstdin {
{ (%stdin) run } execute0
} bind def
end % userdict
pdfdict begin
% ======================== File parsing ======================== %
% Read the cross-reference and trailer sections.
/traileropdict mark
(<<) cvn { mark } bind
(>>) cvn /.dicttomark load
([) cvn { mark } bind % ditto
(]) cvn dup load
/true true
/false false
/null null
/R { /resolveR cvx 3 packedarray cvx } bind % see Objects below
/startxref /exit load
.dicttomark readonly def
% Because of EOL conversion, lines with fixed contents might be followed
% by one or more blanks.
/lineeq % <filestr> <conststr> lineeq <bool>
{ anchorsearch
{ pop { ( ) anchorsearch not { () eq exit } if pop } loop }
{ pop false }
ifelse
} bind def
/linene { lineeq not } bind def
% Read (mostly scan) the cross-reference table.
/readxref % <pos> readxref <trailerdict>
{ PDFoffset add PDFfile exch setfileposition
% In some PDF files, this position actually points to
% white space before the xref line. Skip over this here.
{ PDFfile fileposition PDFfile read pop 32 gt { exit } if pop
} loop
PDFfile exch setfileposition
PDFfile pdfstring readline pop
(xref) linene { /readxref cvx /syntaxerror signalerror } if
% Store the xref table entry position for each object.
% We only need to read the run headers, not every entry.
{ PDFfile token pop % first object # or trailer
dup /trailer eq { pop exit } if
PDFfile pdfstring readline pop
token pop % entry count
exch pop exch
% This section might be adding new objects:
% ensure that Objects and Generations are big enough.
% Stack: count obj#
2 copy add growPDFobjects
PDFfile fileposition 3 -1 roll
{ Objects 2 index lget null eq % later update might have set it
{ Objects 2 index 2 index cvx lput }
if exch 1 add exch 20 add
}
repeat PDFfile exch setfileposition pop
} loop
PDFfile traileropdict .pdfrun
} bind def
% Open a PDF file and read the header, trailer, and cross-reference.
/pdfopen % <file> pdfopen <dict>
{ pdfdict readonly pop % can't do it any earlier than this
15 dict begin
/LocalResources 0 dict def
/PSLevel1 where { pop } { /PSLevel1 false def } ifelse
cvlit /PDFfile exch def
/PDFsource PDFfile def
PDFfile dup 0 setfileposition pdfstring readstring
not {/pdfopen cvx /syntaxerror signalerror} if
(%PDF-) search not {/pdfopen cvx /syntaxerror signalerror} if
length /PDFoffset exch def pop cvr /PDFversion exch def
PDFfile dup dup 0 setfileposition bytesavailable
% Scan backwards over trailing control-character garbage
% (nulls, ^Zs, EOLs).
{ 1 sub 2 copy setfileposition 1 index read pop
32 ge {exit} if
} loop
% Stack: PDFfile endpos
% The top of the stack is now the file position of the last
% non-garbage character.
% We can't use prevline to check for the %%EOF, because if the
% %%EOF isn't followed by an EOL, prevline will read past the
% end of the file, and the file will get closed.
5 sub 2 copy setfileposition
1 index (xxxxxx) readstring pop
dup (\015%%EOF) eq exch (\012%%EOF) eq or not
{ /pdfopen cvx /syntaxerror signalerror } if
1 add setfileposition
prevline cvi % xref start position
exch PDFfile exch setfileposition
prevline (startxref) linene { /pdfopen cvx /syntaxerror signalerror } if
pop
% Stack: xrefpos
initPDFobjects
% Read the last cross-reference table.
readxref /Trailer exch def
Trailer /Encrypt known
{ pdf_process_Encrypt % signal error
}
if
% Read any previous cross-reference tables.
Trailer { /Prev .knownget not { exit } if readxref } loop
% Create and initialize some caches.
/PageCount pdfpagecount def
/PageNumbers PageCount dict def
/PageIndex PageCount array def
% Copy bookmarks (outline) to the output.
Trailer /Root oget /Outlines knownoget
{ /First knownoget
{ { dup writeoutline /Next knownoget not { exit } if } loop } if
}
if
currentdict end
} bind def
% Write the outline structure for a file. Uses linkdest (below).
/writeoutline % <outlinedict> writeoutline -
{ mark
0 2 index /First knownoget
{ { exch 1 add exch /Next knownoget not { exit } if } loop }
if
% stack: dict mark count
dup 0 eq
{ pop 1 index
}
{ 2 index /Count knownoget { 0 lt { neg } if } if
/Count exch 3 index
}
ifelse linkdest /Title oget /Title exch /OUT pdfmark
/First knownoget
{ { dup writeoutline /Next knownoget not { exit } if } loop }
if
} bind def
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -