summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Resource/Init/pdf_draw.ps')
-rw-r--r--Resource/Init/pdf_draw.ps855
1 files changed, 632 insertions, 223 deletions
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
index a359a9c1..1deb0526 100644
--- a/Resource/Init/pdf_draw.ps
+++ b/Resource/Init/pdf_draw.ps
@@ -419,14 +419,43 @@ end
% Some functions used to implement phases of HT and HTP
/sethalftones {
+ % As is so often the case, if we get an error we need to clean up the stack, but we can't
+ % use mark/cleartomark, because the action which caused the error may have left a mark
+ % on the stack. So we need to define our own mark. On an error we'll clean up the stack
+ % until we reach this unique key on the stack
+ /SethalftonesMark exch
+
dup /Default eq {
- pop .setdefaulthalftone
- } {
- resolvehalftone sethalftone
+ pop .setdefaulthalftone pop
+ }
+ {
+ {resolvehalftone} stopped
+ {
+ (\n **** Error resolving halftone. Ignoring the halftone, output may be incorrect.\n)
+ pdfformaterror
+ % Clean up the stack by checking every entry until we find our unique key
+ {/SethalftonesMark eq {exit} if} loop
+ }
+ {
+ {sethalftone} stopped
+ {
+ (\n **** Error setting halftone. Ignoring the halftone, output may be incorrect.\n)
+ pdfformaterror
+ % Clean up the stack by checking every entry until we find our unique key
+ {/SethalftonesMark eq {exit} if} loop
+ }
+ {
+ pop
+ }ifelse
+ }ifelse
} ifelse
} bind executeonly def
/sethalftonephases {
- aload pop -1 2 index 2 index .setscreenphase pop pop
+ {aload pop -1 2 index 2 index .setscreenphase pop pop} stopped
+ {
+ (\n **** Error setting halftone phase. Ignoring the phase, output may be incorrect.\n)
+ pdfformaterror
+ } if
} bind executeonly def
/HT {
@@ -549,9 +578,25 @@ end
cleartomark //null exit
} if
gsave //nodict begin
- /CS knownoget {
+ dup /CS knownoget {
+ exch pop
resolvecolorspace dup setgcolorspace csput
- } if
+ }
+ {
+ % Group attributes dictionaries are supposed to contain a /CS
+ % entry, but Acrobat apparently also handles a /ColorSpace....
+ /ColorSpace knownoget {
+ ( **** Error: A transparency group XObject has a /ColorSpace instead of /CS attribute.\n)
+ pdfformaterror
+ resolvecolorspace dup setgcolorspace csput
+ }
+ {
+ ( **** Error: Ignoring a transparency group XObject without /CS attribute.\n)
+ pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
+ cleartomark //null exit
+ }ifelse
+ } ifelse
aload pop setcolor [ currentgray ]
end grestore
/GrayBackground exch 3 2 roll
@@ -643,9 +688,19 @@ def
resolvecolorspace dup setgcolorspace csput
//true % use currentcolorspace
} {
- % inheriting the colorspace -- make sure Device* spaces are not CIEBased
- forceDefaultCS currentcolorspace 0 get .knownget { exec } if
- //false % no defined colorspace
+ % Group attributes dictionaries are supposed to contain a /CS
+ % entry, but Acrobat apparently also handles a /ColorSpace....
+ dup /Group oget /ColorSpace knownoget {
+ ( **** Error: A transparency group attribute dictionary has a /ColorSpace instead of /CS attribute.\n)
+ pdfformaterror
+ resolvecolorspace dup setgcolorspace csput
+ //true % use currentcolorspace
+ }
+ {
+ % inheriting the colorspace -- make sure Device* spaces are not CIEBased
+ forceDefaultCS currentcolorspace 0 get .knownget { exec } if
+ //false % no defined colorspace
+ } ifelse
} ifelse
3 -1 roll dup
dup 4 1 roll /BBox get aload pop .begintransparencymaskgroup
@@ -1066,6 +1121,8 @@ currentdict end readonly def
//true
} ifelse {
dup dup type /arraytype eq { 0 get } if
+ dup type /packedarraytype eq {exch pop exec dup} if
+
//csrdict exch .knownget {
exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
} {
@@ -1423,8 +1480,12 @@ drawopdict begin
} {
clippath
} ifelse
- //null setup_trans
+ % If we get an error, just emit an empty box
+ { pathbbox } stopped { 0 0 0 0 } if
+ 4 array astore
grestore
+ //null
+ setup_trans
//do_shade exec
teardown_trans
} {
@@ -2210,21 +2271,15 @@ currentdict /last-ditch-bpc-csp undef
} bind executeonly def
/doimagesmask { % <imagemask> doimagesmask -
- PDFusingtransparency {
- currentdict /SMask knownoget
+ PDFusingtransparency not
+ /PreserveSMask /GetDeviceParam .special_op { exch pop } { //false } ifelse
+ or {
+ % not using transparency OR the device supports SMask (e.g. pdfwrite)
+ doimage
} {
- //false
- } ifelse
- { % We are doing transparency and SMask is present in the image
- % stack: <imagemask> <SMask>
- /PreserveSMask /GetDeviceParam .special_op {
- exch pop
- }{
- //false
- }ifelse
- {
- pop % pdfwrite will process SMask directly during 'doimage'
- } {
+ currentdict /SMask knownoget {
+ % We are doing transparency and SMask is present in the image
+ % stack: <imagemask> <SMask>
.begintransparencymaskimage
PDFfile fileposition exch
gsave //nodict begin
@@ -2236,34 +2291,44 @@ currentdict /last-ditch-bpc-csp undef
end grestore
PDFfile exch setfileposition
0 .endtransparencymask
- } ifelse
- << /Subtype /Group /Isolated //true
- /.image_with_SMask //true
- % pdfwrite needs : see gs/src/ztrans.c, gs/src/gdevpdft.c
- % Code to deal with a Matte in the SMask. We know the image dictionary must have an SMask
- % entry if we get here, so we don't need to check its existence. Just pull it out and see if
- % the SMask has a Matte entry. If it does, get the ColorSpace from the parent image and
- % put a /CS key with that colour space in the Group that we manufacture. Bug #700686
- % We also need to actually set the current colour space to be the same as the group
- % code only picks up the current colour space, not the space from the dictionary.
- currentdict /SMask get /Matte known {/CS currentdict /ColorSpace get dup pdfopdict /cs get exec } if
- >> 0 0 1 1 .begintransparencygroup
- doimage
- .endtransparencygroup
- % tell the compositor we're done with the SMask.
- % Note that any SMask in the ExtGState should be reapplied
- % by the next call to setfill(stroke)state AND this relies
- % on our lazy evaulation of SMask groups
- //false << /Subtype /None >> 0 0 0 0 .begintransparencymaskgroup
- } {
- .currentSMask //null ne {
- % the image doesn't have an SMask, but the ExtGState does, force a group.
- << /Subtype /Group /Isolated //true >> 0 0 1 1 .begintransparencygroup
+ << /Subtype /Group /Isolated //true
+ /.image_with_SMask //true
+ % pdfwrite needs : see gs/src/ztrans.c, gs/src/gdevpdft.c
+ % Code to deal with a Matte in the SMask. We know the image dictionary must have an SMask
+ % entry if we get here, so we don't need to check its existence. Just pull it out and see if
+ % the SMask has a Matte entry. If it does, get the ColorSpace from the parent image and
+ % put a /CS key with that colour space in the Group that we manufacture. Bug #700686
+ % We also need to actually set the current colour space to be the same as the group
+ % code only picks up the current colour space, not the space from the dictionary.
+ currentdict /SMask get /Matte known {/CS currentdict /ColorSpace get dup pdfopdict /cs get exec } if
+ >> 0 0 1 1
+ .begintransparencygroup
+ .currentstrokeconstantalpha .currentfillconstantalpha .currentshapealpha .currentopacityalpha 5 -1 roll
+ 1 .setfillconstantalpha 1 .setstrokeconstantalpha
+ 1 .setopacityalpha 1 .setshapealpha
doimage
+ .setopacityalpha .setshapealpha .setfillconstantalpha .setstrokeconstantalpha
.endtransparencygroup
- }
- { doimage }
- ifelse
+ % tell the compositor we're done with the SMask.
+ % Note that any SMask in the ExtGState should be reapplied
+ % by the next call to setfill(stroke)state AND this relies
+ % on our lazy evaulation of SMask groups
+ //false << /Subtype /None >> 0 0 0 0 .begintransparencymaskgroup
+ } {
+ % We don't have an SMask in the image but there might be an SMask in the ExtGState
+ .currentSMask //null ne {
+ % the image doesn't have an SMask, but the ExtGState does, force a group.
+ << /Subtype /Group /Isolated //true >> 0 0 1 1
+ .begintransparencygroup
+ .currentstrokeconstantalpha .currentfillconstantalpha .currentshapealpha .currentopacityalpha 5 -1 roll
+ 1 .setopacityalpha 1 .setshapealpha
+ doimage
+ .setopacityalpha .setshapealpha .setfillconstantalpha .setstrokeconstantalpha
+ .endtransparencygroup
+ } {
+ doimage
+ } ifelse
+ } ifelse
} ifelse
} bind executeonly def
@@ -2315,6 +2380,9 @@ currentdict /last-ditch-bpc-csp undef
/doimage { % <imagemask> doimage -
% imagedict is currentdict, gets popped from dstack
+ %% We must save the colour space, in case it gets changed. I did try doing this
+ %% at a higher level (/Do) but that caused numerous problems with pdfwrite.
+ currentcolorspace exch
%% save the current rendering intent
.currentrenderintent exch
@@ -2336,7 +2404,12 @@ currentdict /last-ditch-bpc-csp undef
makemaskimage
} if
% Stack: datasource imagemask
- gsave 1 1 moveto 0 0 lineto /image setup_trans grestore
+ gsave 1 1 moveto 0 0 lineto
+ % If we get an error, just emit an empty box
+ { pathbbox } stopped { 0 0 0 0 } if
+ 4 array astore grestore
+ /image
+ setup_trans
{ currentdict end setfillstate //true ValidateDecode { imagemask } }
{ ColorSpace setgcolorspace currentdict end setfillblend //false ValidateDecode { image } }
ifelse
@@ -2361,6 +2434,13 @@ currentdict /last-ditch-bpc-csp undef
%% restore the rendering intent
.setrenderingintent
+ %% and restore the colour space. We need to do this in a stopped context because
+ %% if we are rendering a glyph, the cache device will throw an error if we try
+ %% to change colour space (even when the new space is the same as the old space)
+ %% We can't tell if we are rendering a bitmap for a glyph, and its hard to compare
+ %% colour spaces, so just ignore errors for now.
+ {setcolorspace} stopped {pop} if
+
teardown_trans
} bind executeonly def
@@ -3043,7 +3123,7 @@ end
} ifelse
} ifelse
}
- { 0 setgray //true} ifelse
+ { //false } ifelse
} bind executeonly def
% Draw the border. Currently, we ignore requests for beveling, and we
@@ -3051,17 +3131,20 @@ end
/strokeborder { % <annot> <width> <dash> strokeborder -
1 index 0 ne { % do not draw if border width is 0
gsave
- 2 index annotsetcolor
- {
+% 2 index annotsetcolor
+% {
0 setdash dup setlinewidth
- exch annotrect
+ exch dup annotrect
+ 5 -1 roll /RD knownoget {
+ applyRD
+ } if
2 { 4 index sub 4 1 roll } repeat
2 { 4 index 0.5 mul add 4 1 roll } repeat
rectstroke pop
grestore
- } {
- pop pop pop
- } ifelse
+% } {
+% pop pop pop
+% } ifelse
} {
pop pop pop
}ifelse
@@ -3094,12 +3177,16 @@ end
% Scaling due to -dPDFFitPage is not undone, to keep the correct border width
% compared to the size of the surrounding marks.
//systemdict /NoUserUnit .knownget not { //false } if not
- //systemdict /PDFFitPage known not and { % UserUnit is ignored if -dPDFFitPage
+ //systemdict /PDFFitPage known not and
+ % Don't apply USerUnit if we are passing it to the device
+ /PassUserUnit /GetDeviceParam .special_op {exch pop} {//false} ifelse not and
+ { % UserUnit is ignored if -dPDFFitPage
Page /UserUnit knownoget { div } if
} if
{} 2 index /S knownoget {
/D eq { 2 index /D knownoget not { {3} } if exch pop } if
- } if 3 -1 roll pop strokeborder
+ } if
+ 3 -1 roll pop strokeborder
} {
dup 2 get
exch dup length 3 gt { 3 get } { pop {} } ifelse
@@ -3138,23 +3225,39 @@ end
% Scaling due to -dPDFFitPage is not undone, to keep the correct border width
% compared to the size of the surrounding marks.
//systemdict /NoUserUnit .knownget not { //false } if not
- //systemdict /PDFFitPage known not and { % UserUnit is ignored if -dPDFFitPage
+ //systemdict /PDFFitPage known not and
+ % Don't apply USerUnit if we are passing it to the device
+ /PassUserUnit /GetDeviceParam .special_op {exch pop} {//false} ifelse not and
+ { % UserUnit is ignored if -dPDFFitPage
Page /UserUnit knownoget { div } if
} if
{} 2 index /S knownoget {
/D eq { 2 index /D knownoget not { {3} } if exch pop } if
} if
3 index /CA knownoget {.setopacityalpha} if
- 3 -1 roll pop 2 index annotsetcolor {0 setdash setlinewidth stroke} if
+ 3 -1 roll pop
+% 2 index annotsetcolor {
+ 0 setdash setlinewidth stroke
+% } if
} {
dup 2 get
- exch dup length 3 gt { 3 get } { pop {} } ifelse
- 3 index /CA knownoget {.setopacityalpha} if
- 2 index annotsetcolor {0 setdash setlinewidth stroke} if
+ % If element 3 of the /Border array is 0, then don't draw the border
+ dup 0 ne {
+ exch dup length 3 gt { 3 get } { pop {} } ifelse
+ 3 index /CA knownoget {.setopacityalpha} if
+% 2 index annotsetcolor {
+ 0 setdash setlinewidth stroke
+% } if
+ }{
+ pop pop
+ } ifelse
} ifelse
} {
3 index /CA knownoget {.setopacityalpha} if
- 1 {} 2 index annotsetcolor {0 setdash setlinewidth stroke} if
+ 1 {}
+% 2 index annotsetcolor {
+ 0 setdash setlinewidth stroke
+% } if
} ifelse
pop
grestore
@@ -3241,12 +3344,24 @@ end
1 index /DA fget not {
1 index /V fget {
<EFBBBF> anchorsearch {
- pop /Helvetica findfont 12 scalefont setfont
+ pop /Helvetica findfont
+ 12 scalefont setfont
} {
<FEFF> anchorsearch {
pop pop /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont
} {
- pop /Helvetica findfont 12 scalefont setfont
+ pop /Helvetica findfont
+ % re-encode the font to PDFDocEncoding
+ dup length dict begin
+ {
+ 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse
+ } forall
+ /Encoding /PDFDocEncoding /Encoding findresource def
+ /FontName /Helvetica-PDFDocEncoding def
+ currentdict
+ end
+ /Helvetica-PDFDocEncoding exch definefont
+ 12 scalefont setfont
}ifelse
}ifelse
} if
@@ -3318,109 +3433,151 @@ end
% } if
% } if
- dup /AP knownoget {
- dup /N known not {
- ( **** Error: Appearance dictionary (AP) lacks the mandatory normal (N) appearance.\n)
- pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
+ % Acrobat doesn't draw Widget annotations unles they have both /FT
+ % (which is defined as required) and /T keys present. Annoyingly
+ % these can either be inherited from the Form Definition Field
+ % dictionary (via the AcroForm tree) or present directly in the
+ % annotation, so we need to check the annotation to make sure its
+ % a Widget, then follow any /Parent key up to the root node
+ % extracting and storing any FT or T keys as we go (we only care if
+ % these are present, their value is immaterial). If after all that
+ % both keys are not present, then we don't draw the annotation.
+
+ dup /Subtype get /Widget eq {
+ dup /FT known 1 index /T known and not {
+ dup
+ {
+ dup /FT knownoget {
+ /FT exch 3 index 3 1 roll put
+ } if
+ dup /T knownoget {
+ /T exch 3 index 3 1 roll put
+ } if
+ /Parent knownoget not {
+ exit
+ } if
+ } loop
} if
- //false
- [/N /R /D] {
- % stack: scalex scaley annot appearance false key
- 2 index exch knownogetdict {
- exch not exit
+ dup /FT known 1 index /T known and {
+ //true
+ } {
+ ( **** Warning: A Widget annotation dictionary lacks either the FT or T key.\n)
+ pdfformaterror
+ ( Acrobat ignores such annotations, annotation will not be rendered.\n)
+ pdfformaterror
+ ( Output may not be as expected.\n) pdfformaterror
+ //false
+ } ifelse
+ } {
+ //true
+ }ifelse
+
+ {
+ dup /AP knownoget {
+ dup /N known not {
+ ( **** Error: Appearance dictionary (AP) lacks the mandatory normal (N) appearance.\n)
+ pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
} if
- } forall
- % stack: scalex scaley annot appearance value true
- % stack: scalex scaley annot appearance false
- dup {
- pop exch pop
+ //false
+ [/N /R /D] {
+ % stack: scalex scaley annot appearance false key
+ 2 index exch knownogetdict {
+ exch not exit
+ } if
+ } forall
+ % stack: scalex scaley annot appearance value true
+ % stack: scalex scaley annot appearance false
+ dup {
+ pop exch pop
% Acrobat Distiller produces files in which this Form
% XObject lacks Type and Subtype keys. This is illegal,
% but Acrobat Reader accepts it. The only way we can
% tell whether this is a Form or a set of sub-appearances
% is by testing for the stream Length or File key.
% If the stream lacks Length key, try File key.
- dup /Length knownoget { type /integertype eq } { //false } ifelse
- 1 index /File knownoget { type /filetype eq or } if {
- % If this is a form then simply use it
- //true
- } {
- 1 index /AS knownoget not {
- % If we do not have AS then use any appearance
- { exch pop oforce exit } forall //true
+ dup /Length knownoget { type /integertype eq } { //false } ifelse
+ 1 index /File knownoget { type /filetype eq or } if {
+ % If this is a form then simply use it
+ //true
} {
- % Stack: annot Ndict AS
- % Get the specified appearance. If no appearance, then
- % display nothing - set stack = false.
- knownoget
+ 1 index /AS knownoget not {
+ % If we do not have AS then use any appearance
+ { exch pop oforce exit } forall //true
+ } {
+ % Stack: annot Ndict AS
+ % Get the specified appearance. If no appearance, then
+ % display nothing - set stack = false.
+ knownoget
+ } ifelse
} ifelse
+ } {
+ exch pop % discard useless AP dictionary
} ifelse
- } {
- exch pop % discard useless AP dictionary
- } ifelse
% Stack: scalex scaley annot appearance true
% Stack: scalex scaley annot false
- {
- dup type /dicttype eq {
+ {
+ dup type /dicttype eq {
% Draw appearance
% Initialize graphic following "7.4.4 Appearance Streams"
- q graphicsbeginpage textbeginpage
- 1 index annotrect pop pop translate
- 3 index 3 index scale % Apply scale factors
- dup /BBox knownoget {
- 1 index /Matrix knownoget not { {1 0 0 1 0 0} } if
- .bbox_transform pop pop
- % Compensate for non-zero origin of BBox
- neg exch neg exch translate
- } if
- DoForm Q
- } {
- ( **** Error: Annotation's appearance is not a dictionary.\n)
- pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
- } ifelse
- } if
- } {
- dup /MK knownoget { % mk
- dup /BG knownoget { % mk bg
- dup length % mk bg len
- //set_bc_color exch .knownget {
- gsave
- exec
- 3 index 3 index scale
- 1 index annotrect rectfill
- grestore
+ q graphicsbeginpage textbeginpage
+ 1 index annotrect pop pop translate
+ 3 index 3 index scale % Apply scale factors
+ dup /BBox knownoget {
+ 1 index /Matrix knownoget not { {1 0 0 1 0 0} } if
+ .bbox_transform pop pop
+ % Compensate for non-zero origin of BBox
+ neg exch neg exch translate
+ } if
+ DoForm Q
} {
- pop
+ ( **** Error: Annotation's appearance is not a dictionary.\n)
+ pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
} ifelse
} if
- dup /BC knownoget {
- dup length
- //set_bc_color exch .knownget {
- gsave
- exec
- 1 setlinewidth
- 3 index 3 index scale
- 1 index annotrect rectstroke
- grestore
- } {
- pop
- } ifelse
+ } {
+ dup /MK knownoget { % mk
+ dup /BG knownoget { % mk bg
+ dup length % mk bg len
+ //set_bc_color exch .knownget {
+ gsave
+ exec
+ 3 index 3 index scale
+ 1 index annotrect rectfill
+ grestore
+ } {
+ pop
+ } ifelse
+ } if
+ dup /BC knownoget {
+ dup length
+ //set_bc_color exch .knownget {
+ gsave
+ exec
+ 1 setlinewidth
+ 3 index 3 index scale
+ 1 index annotrect rectstroke
+ grestore
+ } {
+ pop
+ } ifelse
+ } if
+ pop
} if
- pop
- } if
- dup can-regenerate-ap {
- make_tx_da
- dup /UpdatedAP //true put
- 3 copy drawwidget
- } if
- } ifelse
+ dup can-regenerate-ap {
+ make_tx_da
+ dup /UpdatedAP //true put
+ 3 copy drawwidget
+ } if
+ } ifelse
+ } if
pop pop pop
} bind executeonly def
+
currentdict /set_bc_color undef
% For annotation object we have to determine the size of the output rectangle
@@ -3471,6 +3628,23 @@ currentdict /set_bc_color undef
} ifelse
} bind executeonly def
+/applyRD {
+ % x y w h [l t r b]
+ dup 0 get % x y w h [] l
+ 6 -1 roll add
+ 5 1 roll %x+l y w h []
+ dup 1 get %x+l y w h [] b
+ 5 -1 roll add %x+l w h [] b+y
+ 4 1 roll %x+l y+b w h []
+ aload pop %x+l y+b w h l t r b
+ exch %x+l y+b w h l t b r
+ 4 -1 roll add %x+l y+b w h t b r+l
+ 3 1 roll add %x+l y+b w h r+l t+b
+ 3 -1 roll exch sub %x+l y+b w r+l h-(t+b)
+ 3 1 roll sub %x+l y+b h-(t+b) w-(r+l)
+ exch
+} bind executeonly def
+
% Draw an annotation.
/drawannottypes 20 dict begin
@@ -3569,16 +3743,30 @@ currentdict /set_bc_color undef
{
gsave
dup /ca knownoget {.setopacityalpha} if
- dup annotrect rectfill
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ } if
+ rectfill
grestore
dup /CA knownoget {.setopacityalpha} if
- drawborder
+ dup annotsetcolor {
+ drawborder
+ } if
//false
}{
- pop
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ } if
+ drawopdict /re get exec
+ dup annotsetcolor {
+ strokeborderpath
+ } if
} ifelse
//endannottransparency exec
grestore
+ //false
}ifelse
} bind executeonly def
@@ -3608,11 +3796,17 @@ currentdict /set_bc_color undef
} {
gsave
//startannottransparency exec
- dup annotrect 4 2 roll exch 3 index 2 div add exch 2 index 2 div add
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ } if
+ 4 2 roll exch 3 index 2 div add exch 2 index 2 div add
translate //drawellipse exec
dup
fillborderpath
- strokeborderpath
+ dup annotsetcolor {
+ strokeborderpath
+ } if
//endannottransparency exec
grestore
//false
@@ -3661,8 +3855,14 @@ currentdict /set_bc_color undef
fill
grestore
dup /CA knownoget {.setopacityalpha} if
- strokeborderpath
- } if
+ dup annotsetcolor {
+ strokeborderpath
+ } if
+ } {
+ dup annotsetcolor {
+ strokeborderpath
+ } if
+ } ifelse
//endannottransparency exec
//false
grestore
@@ -3795,7 +3995,7 @@ currentdict /set_bc_color undef
fillborderpath
grestore
} bind executeonly def
- /None {} bind executeonly def
+ /None {pop} bind executeonly def
/Butt {
dup
/BS knownoget {
@@ -3880,36 +4080,50 @@ currentdict /set_bc_color undef
} {
gsave
//startannottransparency exec
- dup /L knownoget {
- 1 index /LE knownoget {
- gsave
- 1 index aload pop % x1 y1 x2 y2
- 3 -1 roll sub % x1 x2 dy
- 3 1 roll exch sub % dy dx
- 2 copy translate
- atan
- rotate
- dup 0 get dup //LineEnd_dict exch known not {pop /None} if //LineEnd_dict exch get 3 index exch exec
- grestore
- gsave
- 1 index aload pop % x1 y1 x2 y2
- 3 -1 roll sub % x1 x2 dy
- 3 1 roll exch sub % dy dx
- 2 copy translate
- atan 180 add
- rotate
- 1 get dup //LineEnd_dict exch known not {pop /None} if //LineEnd_dict exch get 3 index exch exec
- grestore
- }if
- aload pop 4 2 roll
- moveto lineto
- strokeborderpath
- }{
- ( **** Error: Invalid L array for Line, annotation has not been drawn.\n)
- pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
- pop
- } ifelse
+ dup annotsetcolor {
+ dup /L knownoget {
+ 1 index /LE knownoget { % <annot> [x1 y1 x2 y2] [LE1 LE2]
+ gsave
+ 1 index aload pop % <annot> [x1 y1 x2 y2] [LE1 LE2] x1 y1 x2 y2
+ 3 -1 roll sub % <annot> [x1 y1 x2 y2] [LE1 LE2] x1 x2 dy
+ 3 1 roll exch sub % <annot> [x1 y1 x2 y2] [LE1 LE2] dy dx
+ 3 index aload pop 4 2 roll pop pop
+ translate
+ 0 0 moveto
+ atan % <annot> [x1 y1 x2 y2] [LE1 LE2]
+ rotate
+ dup 1 get % <annot> [x1 y1 x2 y2] [LE1 LE2] LE1
+ dup //LineEnd_dict exch known not
+ {
+ pop /None
+ } if
+ //LineEnd_dict exch % <annot> [x1 y1 x2 y2] [LE1 LE2] <dict> LE1
+ get % <annot> [x1 y1 x2 y2] [LE1 LE2] {}
+ 3 index exch % <annot> [x1 y1 x2 y2] [LE1 LE2] <annot> {}
+ exec
+ grestore
+ gsave
+ 1 index aload pop % x1 y1 x2 y2
+ 3 -1 roll sub % x1 x2 dy
+ 3 1 roll exch sub % dy dx
+ 3 index aload pop pop pop
+ translate
+ 0 0 moveto
+ atan 180 add
+ rotate
+ 0 get dup //LineEnd_dict exch known not {pop /None} if //LineEnd_dict exch get 3 index exch exec
+ grestore
+ }if
+ aload pop 4 2 roll
+ moveto lineto
+ strokeborderpath
+ }{
+ ( **** Error: Invalid L array for Line, annotation has not been drawn.\n)
+ pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
+ pop
+ } ifelse
+ } if
//endannottransparency exec
//false
grestore
@@ -3977,14 +4191,16 @@ currentdict /set_bc_color undef
/Link { % <annot> -> <false>
//startannottransparency exec
- dup drawborder dup calc_annot_scale
- 2 copy mul 0 ne
- {3 -1 roll drawwidget //false}
- {
- pop pop
- ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
- }ifelse
+ dup annotsetcolor {
+ dup drawborder dup calc_annot_scale
+ 2 copy mul 0 ne
+ {3 -1 roll drawwidget //false}
+ {
+ pop pop
+ ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
+ }ifelse
+ } if
//endannottransparency exec
} bind executeonly def
@@ -3998,7 +4214,8 @@ currentdict /set_bc_color undef
1 setlinewidth
1 setlinecap
1 setlinejoin
- dup annotsetcolor {
+ dup annotsetcolor
+ {
dup calc_annot_scale
2 copy mul 0 ne
{
@@ -4047,7 +4264,8 @@ currentdict /set_bc_color undef
//true
} {
0 setlinecap
- dup annotsetcolor {
+ dup annotsetcolor
+ {
dup calc_annot_scale
2 copy mul 0 ne
{
@@ -4087,7 +4305,8 @@ currentdict /set_bc_color undef
//true
} {
0 setlinecap
- dup annotsetcolor {
+ dup annotsetcolor
+ {
dup calc_annot_scale
2 copy mul 0 ne
{
@@ -4149,7 +4368,8 @@ currentdict /set_bc_color undef
//true
} {
0 setlinecap
- dup annotsetcolor {
+ dup annotsetcolor
+ {
/QuadPoints knownoget {
aload length 8 idiv {
6 -2 roll
@@ -4161,7 +4381,9 @@ currentdict /set_bc_color undef
} repeat
PDFusingtransparency {
//emptydict
- pathbbox 2 index add exch 3 index add exch .begintransparencygroup
+ % If we get an error, just emit an empty box
+ { pathbbox } stopped { 0 0 0 0 } if
+ 2 index add exch 3 index add exch .begintransparencygroup
/Multiply .setblendmode
fill
.endtransparencygroup
@@ -4182,7 +4404,8 @@ currentdict /set_bc_color undef
//true
} {
//startannottransparency exec
- dup annotsetcolor {
+ dup annotsetcolor
+ {
dup calc_annot_scale
2 copy mul 0 ne
{
@@ -4323,18 +4546,37 @@ currentdict /set_bc_color undef
}{
//false
} ifelse
- {dup annotrect
- %% Somewhat horrifyingly, rectfill maps directly to the device fill_rectangle
- %% method, which bypasses transparency (!!) So we construct the rectangle,
- %% and fill it, manually instead....
- gsave 4 2 roll moveto 1 index 0 rlineto
- 0 exch rlineto neg 0 rlineto closepath fill grestore
+ {
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ } if
+ rectfill
} if
%% get and process the default appearance string, if we don't have one, use a default
/DA_Action_Dict
<<
- /Tf {exch dup /Helv eq {pop /Helvetica findfont exch scalefont setfont}{findfont exch scalefont setfont}ifelse}
+ /Tf
+ {
+ exch dup /Helv eq
+ {
+ pop /Helvetica dup findfont
+ }
+ {dup findfont}ifelse
+
+ % re-encode the font to PDFDocEncoding
+ dup length dict begin
+ {
+ 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse
+ } forall
+ /Encoding /PDFDocEncoding /Encoding findresource def
+ /FontName /Helvetica-PDFDocEncoding def
+ currentdict
+ end
+ definefont
+ exch scalefont setfont
+ }
/r {aload pop setrgbcolor} % Can't find this actually defined anywhere, but Acrobat seems to honour it :-(
/rg {setrgbcolor}
/RG {setrgbcolor}
@@ -4380,27 +4622,108 @@ currentdict /set_bc_color undef
{cleartomark pop} ifelse
} {
0 setgray
- /Helvetica findfont 12 scalefont setfont
+ /Helvetica findfont
+ % re-encode the font to PDFDocEncoding
+ dup length dict begin
+ {
+ 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse
+ } forall
+ /Encoding /PDFDocEncoding /Encoding findresource def
+ /FontName /Helvetica-PDFDocEncoding def
+ currentdict
+ end
+ /Helvetica-PDFDocEncoding exch definefont
+ 12 scalefont setfont
}ifelse
%% draw the border, if we don't have a border style dictionary, draw a default one.
- dup /BS knownoget {
+ dup /BS knownoget
+ {
pop dup drawborder
}{
newpath
0 setgray 1 setlinewidth
- dup annotrect 4 -1 roll 1 add 4 -1 roll 1 add 4 -1 roll 2 sub 4 -1 roll 2 sub
- 4 2 roll moveto
- currentpoint exch 3 index add exch lineto
- currentpoint 2 index add lineto
- exch currentpoint 3 1 roll exch sub exch lineto
- currentpoint 3 -1 roll sub lineto stroke
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ 4 -1 roll 4 -1 roll 4 -1 roll 4 -1 roll
+ 4 2 roll
+ } {
+ 4 -1 roll 1 add 4 -1 roll 1 add 4 -1 roll 2 sub 4 -1 roll 2 sub
+ 4 2 roll
+ }ifelse
+ moveto
+ currentpoint exch 3 index add exch
+ lineto
+ currentpoint 2 index add
+ lineto
+ exch currentpoint 3 1 roll exch sub exch
+ lineto
+ currentpoint 3 -1 roll sub
+ lineto stroke
}ifelse
+ gsave % in case we rotate the contents
%% Start the current point at the top left of the annotation Rect
%%
- dup annotrect 4 -1 roll 2 add 4 -1 roll 2 add 4 -1 roll 4 sub 4 -1 roll 4 sub
- 3 -1 roll add 2 index exch moveto 1 index add
+ dup /Rotate knownoget
+ % x y w h - x' w' x' y'
+ {
+ dup 90 eq {
+ pop
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ } if
+ exch pop 3 -1 roll 2 index
+ moveto 90 rotate
+ 1 index add
+ } {
+ dup 180 eq {
+ pop
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ } if
+ pop 3 -1 roll 1 index add -1 mul exch 1 index -1 mul 4 -1 roll
+ moveto 180 rotate
+ 1 index add
+ }{
+ 270 eq {
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ } if
+ dup 4 -1 roll add 3 -1 roll 3 index add exch
+ moveto 270 rotate
+ exch pop currentpoint
+ pop dup 3 -1 roll add
+ }{
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ 3 -1 roll add 2 index exch
+ moveto 1 index add
+ }{
+ 4 -1 roll 2 add 4 -1 roll 2 add 4 -1 roll 4 sub 4 -1 roll 4 sub
+ 3 -1 roll add 2 index exch
+ moveto 1 index add
+ } ifelse
+ } ifelse
+ } ifelse
+ } ifelse
+ }{
+ dup annotrect
+ 5 index /RD knownoget {
+ applyRD
+ 3 -1 roll add 2 index exch
+ moveto 1 index add
+ }{
+ 4 -1 roll 2 add 4 -1 roll 2 add 4 -1 roll 4 sub 4 -1 roll 4 sub
+ 3 -1 roll add 2 index exch
+ moveto 1 index add
+ } ifelse
+ } ifelse
%% Get the Contents string, if we don't have one, we're done
%%
@@ -4439,7 +4762,6 @@ currentdict /set_bc_color undef
%% and use it immediatley to start the text one line down
%%
currentpoint ..TextHeight sub moveto
-
%% Now we process each character code in the string. If we find
%% a /r/ or /n then we drop a line. If the character would end up
%% outside the Annot Rect, then we drop a line before showing it.
@@ -4453,7 +4775,8 @@ currentdict /set_bc_color undef
} {
1 string dup 0 4 -1 roll
put dup %% llx urx (string) (int) (int)
- stringwidth pop currentpoint pop add 3 index gt {
+ stringwidth pop currentpoint pop add 3 index
+ gt {
currentpoint exch pop 4 index exch ..TextHeight sub moveto
} if
show
@@ -4470,6 +4793,34 @@ currentdict /set_bc_color undef
} ifelse
} if
pop pop
+
+ grestore % in case the contents were rotated
+ dup /CL knownoget {
+ dup length 6 eq {
+ dup aload pop pop pop
+ } {
+ dup length 4 eq {
+ dup aload pop
+ } {
+ pop 0
+ } ifelse
+ } ifelse
+ 4 2 roll
+ exch 4 -1 roll sub
+ 3 1 roll exch sub
+ atan exch
+ aload pop moveto lineto lineto
+ currentpoint
+% stroke
+% 0 1 0 setrgbcolor
+ moveto currentpoint translate 0 0 moveto
+ 360 exch sub rotate
+ currentpoint
+ -5 -8 rlineto
+ moveto
+ 5 -8 rlineto
+ stroke
+ } if
//endannottransparency exec
//false
grestore
@@ -4505,7 +4856,18 @@ currentdict /set_bc_color undef
PDFusingtransparency {
.begintransparencytextgroup
} if
- /Times-Bold findfont exch scalefont setfont % (text) y
+ /Times-Bold findfont
+ % re-encode the font to PDFDocEncoding
+ dup length dict begin
+ {
+ 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse
+ } forall
+ /Encoding /PDFDocEncoding /Encoding findresource def
+ /FontName /Times-Bold-PDFDocEncoding def
+ currentdict
+ end
+ /Times-Bold-PDFDocEncoding exch definefont
+ exch scalefont setfont % (text) y
gsave
0 0 moveto
1 index //false charpath flattenpath pathbbox
@@ -4668,7 +5030,18 @@ currentdict /set_bc_color undef
.begintransparencytextgroup
} if
0 setgray
- /Helvetica findfont 9 scalefont setfont
+ /Helvetica findfont
+ % re-encode the font to PDFDocEncoding
+ dup length dict begin
+ {
+ 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse
+ } forall
+ /Encoding /PDFDocEncoding /Encoding findresource def
+ /FontName /Helvetica-PDFDocEncoding def
+ currentdict
+ end
+ /Helvetica-PDFDocEncoding exch definefont
+ 9 scalefont setfont
2 index aload pop 3 1 roll pop pop 30 sub exch 5 add exch
moveto show
PDFusingtransparency {
@@ -4687,7 +5060,18 @@ currentdict /set_bc_color undef
.begintransparencytextgroup
} if
0 setgray
- /Helvetica findfont 9 scalefont setfont
+ /Helvetica findfont
+ % re-encode the font to PDFDocEncoding
+ dup length dict begin
+ {
+ 1 index /FID ne 2 index /UniqueID ne and { def } { pop pop } ifelse
+ } forall
+ /Encoding /PDFDocEncoding /Encoding findresource def
+ /FontName /Helvetica-PDFDocEncoding def
+ currentdict
+ end
+ /Helvetica-PDFDocEncoding exch definefont
+ 9 scalefont setfont
dup stringwidth pop
2 index aload pop pop exch pop exch sub
exch sub 2 div 2 index aload pop 3 1 roll pop pop 11 sub 3 1 roll add exch moveto
@@ -4748,6 +5132,25 @@ currentdict end readonly def
ifelse
} bind executeonly def
+/.PDFPreserveAnnotType?
+{
+ //false exch
+ /PreserveAnnotTypes where
+ {
+ /PreserveAnnotTypes get
+ {
+ dup /* eq exch 2 index eq or
+ {
+ pop //true exch
+ exit
+ } if
+ } forall
+ pop
+ }
+ {pop pop //true}
+ ifelse
+} bind executeonly def
+
/drawannot { % <annot> drawannot -
dup annotvisible {
gsave
@@ -5050,7 +5453,7 @@ currentdict end readonly def
gsave
dup dup /Subtype knownoget {
- dup //.PDFDrawAnnotType? exec
+ dup //.PDFPreserveAnnotType? exec
{
//preserveannottypes exch .knownget { exec } { //true } ifelse
{
@@ -5068,7 +5471,13 @@ currentdict end readonly def
}ifelse
} if
}
- {pop} ifelse
+ {
+ % Not preserving this type of annotation
+ % discard teh Subtype
+ pop
+ % copy the Annot dictionary and try drawing it instead
+ dup drawannot
+ } ifelse
% type known
} {
pop