📄 pdf_base.ps
字号:
pop true
} {
% Update Objects from GlobalObjects
DEBUG { (%Global=>local: ) print dup == } if
Objects exch GlobalObjects 1 index get lput false
} ifelse
} {
pop false
} ifelse
} bind def
/oforce /exec load def
/oget % <array> <index> oget <object>
% <dict> <key> oget <object>
{ 2 copy get dup xcheck
{ exec dup 4 1 roll put }
{ exch pop exch pop }
ifelse
} bind def
% A null value in a dictionary is equivalent to an omitted key;
% we must check for this specially.
/knownoget
{ 2 copy known
{ oget dup null eq { pop false } { true } ifelse }
{ pop pop false }
ifelse
} bind def
% PDF 1.1 defines a 'foreign file reference', but not its meaning.
% Per the specification, we convert these to nulls.
/F % <file#> <object#> <generation#> F <object>
{ % Some PDF 1.1 files use F as a synonym for f!
count 3 lt { f } { pop pop pop null } ifelse
} bind def
/checkgeneration { % <object#> <generation#> checkgeneration <object#> <OK>
Generations 2 index lget 1 sub 1 index eq {
pop true
} {
Generations 2 index lget 0 eq {
(Warning: reference to free object: )
} {
(Warning: wrong generation: )
} ifelse print 1 index =only ( ) print =only ( R) = false
} ifelse
} bind def
/R { % <object#> <generation#> R <object>
1 index unresolved?
{ /resolveR cvx 3 packedarray cvx }
{ checkgeneration { Objects exch lget } { pop null } ifelse }
ifelse
} bind def
% If we encounter an object definition while reading sequentially,
% we just store it away and keep going.
/objopdict mark
valueopdict { } forall
/endobj dup cvx
.dicttomark readonly def
/obj { % <object#> <generation#> obj <object>
PDFfile objopdict .pdfrun
} bind def
/endobj { % <object#> <generation#> <object> endobj <object>
3 1 roll
% Read the xref entry if we haven't yet done so.
% This is only needed for generation # checking.
1 index unresolved? {
PDFfile fileposition
2 index readxrefentry pop
PDFoffset add PDFfile exch setfileposition
} if
checkgeneration {
% The only global objects we bother to save are
% (resource) dictionaries.
1 index dup gcheck exch type /dicttype eq and {
DEBUG { (%Local=>global: ) print dup == } if
GlobalObjects 1 index 3 index put
IsGlobal 1 index 1 put
} if
Objects exch 2 index lput
} {
pop pop null
} ifelse
} bind def
% When resolving an object reference, we stop at the endobj.
/resolveopdict mark
valueopdict { } forall
/endobj { endobj exit } bind
.dicttomark readonly def
/resolveR % <object#> <generation#> resolveR <object>
{ DEBUG { (%Resolving: ) print 2 copy 2 array astore == } if
1 index unresolved?
{ PDFfile fileposition 3 1 roll
1 index readxrefentry
3 1 roll checkgeneration
{ % Stack: savepos objpos obj#
exch PDFoffset add PDFfile exch setfileposition
PDFfile token pop 2 copy ne
{ (xref error!\n) print /resolveR cvx /rangecheck signalerror
}
if pop PDFfile token pop
PDFfile token pop /obj ne
{ (xref error!\n) print /resolveR cvx /rangecheck signalerror
}
if
pdf_run_resolve % PDFfile resolveopdict .pdfrun
}
{ Objects exch null lput pop null
}
ifelse exch PDFfile exch setfileposition
}
{ pop Objects exch lget
}
ifelse
} bind def
% ================================ Streams ================================ %
% We represent a stream by an executable dictionary that contains,
% in addition to the contents of the original stream dictionary:
% /File - the file or string where the stream contents are stored,
% if the stream is not an external one.
% /FilePosition - iff File is a file, the position in the file
% where the contents start.
% /StreamKey - the key used to decrypt this stream, if any.
% We do the real work of constructing the data stream only when the
% contents are needed.
% Construct a stream. The length is not reliable in the face of
% different end-of-line conventions, but it's all we've got.
%
% PDF files are inconsistent about what may fall between the 'stream' keyword
% and the actual stream data, and it appears that no one algorithm can
% detect this reliably. We used to try to guess whether the file included
% extraneous \r and/or \n characters, but we no longer attempt to do so,
% especially since the PDF 1.2 specification states flatly that the only
% legal terminators following the 'stream' keyword are \n or \r\n, both of
% which are properly skipped and discarded by the token operator.
/stream { % <dict> stream <modified_dict>
dup /F known dup PDFsource PDFfile eq or {
not {
dup /File PDFfile put
dup /FilePosition PDFfile fileposition put
DEBUG { (%FilePosition: ) print dup /FilePosition get == } if
} if
PDFfile fileposition 1 index /Length oget add
PDFfile exch setfileposition
} {
pop
% We're already reading from a stream, which we can't reposition.
% Capture the sub-stream contents in a string.
dup /Length oget string PDFsource exch readstring
not {
(Unexpected EOF in stream!\n) print
/stream cvx /rangecheck signalerror
} if
1 index exch /File exch put
} ifelse
PDFsource token pop
/endstream ne { /stream cvx /syntaxerror signalerror } if
cvx
} bind def
/endstream {
exit
} bind def
% Extract and apply filters.
/filterparms { % <dict> <DPkey> <Fkey> filterparms
% <dict> <parms> <filternames>
exch 2 index exch .knownget not { null } if
exch 2 index exch .knownget not { { } } if
dup type /nametype eq {
1 array astore
1 index null ne { exch 1 array astore exch } if
} if
} bind def
/applyfilters { % <parms> <source> <filternames> applyfilters <stream>
2 index null eq {
{ filter }
} {
{ % Stack: parms stream filtername
2 index 0 get dup null eq { pop } { exch } ifelse filter
exch dup length 1 sub 1 exch getinterval exch
}
} ifelse forall exch pop
} bind def
% Resolve a stream dictionary to a PostScript stream.
% Streams with no filters require special handling:
% - If we are going to interpret their contents, we let endstream
% terminate the interpretation loop;
% - If we are just going to read data from them, we impose
% a SubFileDecode filter that reads just the requisite amount of data.
% Note that, in general, resolving a stream repositions PDFfile.
% Clients must save and restore the position of PDFfile themselves.
/resolvestream { % <streamdict> <readdata?> resolvestream <stream>
1 index /F .knownget {
% This stream is stored on an external file.
(r) file exch
/FDecodeParms /FFilter filterparms
% Stack: readdata? dict parms filternames
4 -1 roll exch
pdf_decrypt_stream
apply_filters
} {
exch dup /FilePosition .knownget {
1 index /File get exch setfileposition
} if
% Stack: readdata? dict
/DecodeParms /Filter filterparms
% Stack: readdata? dict parms filternames
2 index /File get exch
% Stack: readdata? dict parms file/string filternames
pdf_decrypt_stream % add decryption if needed
dup length 0 eq {
% All the PDF filters have EOD markers, but in this case
% there is no specified filter.
pop exch pop
% Stack: readdata? dict file/string
2 index {
% We're going to read data; use a SubFileDecode filter.
1 index /Length oget () /SubFileDecode filter
} {
dup type /filetype ne {
% Use a SubFileDecode filter to read from a string.
0 () SubFileDecode filter
} if
} ifelse
} {
applyfilters
} ifelse
} ifelse
% Stack: readdata? dict file
exch pop exch pop
} bind def
% ============================ Name/number trees ============================ %
/nameoget { % <nametree> <key> nameoget <obj|null>
exch /Names exch .treeget
} bind def
/numoget { % <numtree> <key> numoget <obj|null>
exch /Nums exch .treeget
} bind def
/.treeget { % <key> <leafkey> <tree> .treeget <obj|null>
dup /Kids knownoget {
exch pop .branchget
} {
exch get .leafget
} ifelse
} bind def
/.branchget { % <key> <leafkey> <kids> .branchget <obj|null>
dup length 0 eq {
pop pop pop null
} {
dup length -1 bitshift 2 copy oget
% Stack: key leafkey kids mid kids[mid]
dup /Limits oget aload pop
% Stack: key leafkey kids mid kids[mid] min max
6 index lt {
pop pop
1 add 1 index length 1 index sub getinterval .branchget
} {
5 index gt {
pop
0 exch getinterval .branchget
} {
exch pop exch pop .treeget
} ifelse
} ifelse
} ifelse
} bind def
/.leafget { % <key> <pairs> .leafget <obj|null>
dup length 2 eq {
dup 0 get 2 index eq { 1 oget } { pop null } ifelse
exch pop
} {
dup length -1 bitshift -2 and 2 copy oget
% Stack: key pairs mid pairs[mid]
3 index gt { 0 exch } { 1 index length 1 index sub } ifelse
getinterval .leafget
} ifelse
} bind def
end % pdfdict
.setglobal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -