[gs-cvs] rev 7878 - trunk/gs/lib

alexcher at ghostscript.com alexcher at ghostscript.com
Mon Apr 23 16:59:02 PDT 2007


Author: alexcher
Date: 2007-04-23 16:59:01 -0700 (Mon, 23 Apr 2007)
New Revision: 7878

Modified:
   trunk/gs/lib/pdf_draw.ps
   trunk/gs/lib/pdf_main.ps
   trunk/gs/lib/pdf_ops.ps
Log:
Partly implement AcroForm feature: all fields that provire appearance
streams and text fields with variable text. Bug 687498.

DETAILS:
Although the sample file renders identically to Adobe Acrobat, many things
are not yet coded.
- other types of annotations without appearance streams
- XML formatted text
- multi-line text
- combed text
- right-aligned or centered text with non-0 word and character spacing.

DIFFERENCES:
Progression in rf1025.pdf
Altona*.pdf now report to stdout that Sig field is not implemented.


Modified: trunk/gs/lib/pdf_draw.ps
===================================================================
--- trunk/gs/lib/pdf_draw.ps	2007-04-23 21:46:19 UTC (rev 7877)
+++ trunk/gs/lib/pdf_draw.ps	2007-04-23 23:59:01 UTC (rev 7878)
@@ -1179,6 +1179,9 @@
   /' { ' } def
   /" { " } def
   /TJ { TJ } def
+
+  /Tform { Tform } def  % Text formatting and painting for AcroForm
+                        % without appearance streams.
 end
 
 % ============================== Annotations ============================== %
@@ -1426,6 +1429,148 @@
 } bdef
 currentdict /drawannottypes undef
 
+% ============================ AcroForm fields ============================ %
+
+% Get an attribure of the 0th annotation of a node
+/annot_oget {  % <annot> /Name annot_oget <value>
+  1 index /Kids knownoget {
+    0 oget exch oget exch pop
+  } {
+    oget
+  } ifelse
+} bdef
+
+% All procedures have the signature:
+% <acroform> <field> <annot|field> foo <acroform> <field> <annot|field>
+/draw_terminal_field_dict 4 dict begin
+
+/Btn {
+  1 index /Tf pget not { 0 } if
+  dup 16#20000 and 0 ne {
+    pop % Push button
+    dup /AP known {
+       dup 1 exch drawwidget
+    } {
+      (Piush button without appearance stream is not yet implemented) =
+    } ifelse
+  } {
+    16#10000 and 0 ne {
+        % Radio button
+        dup /AP known {
+          1 index /Kids oget {
+            1 exch drawwidget
+          } forall
+        } {
+          (Radio button without appearance stream is not yet implemented) =
+        } ifelse
+    } {
+        % Checkbox
+        dup /AP known {
+          dup 1 exch drawwidget
+        } {
+          (CkeckBox without appearance stream is not yet implemented) =
+        } ifelse
+    } ifelse
+  } ifelse
+} bdef
+
+/Tx {
+  dup /AP known {
+    dup 1 exch drawwidget
+  } {
+    2 index /NeedAppearances knownoget not { //false } if {
+      dup /AP << /N 10 dict dup cvx begin >> put
+      /Subtype /Form def
+      /BBox [ 0 0 4 index /Rect oget { oforce } forall  3 -1 roll sub abs 3 1 roll sub abs exch ] def
+      /Resources 3 index /DR pget not { 0 dict } if def
+      /File 1000 string dup 3 1 roll def
+      /Length 0 def
+                            % <acroform> <field> <annot> (string)
+      /NullEncode filter    % <acroform> <field> <annot> file 
+
+      dup (BT ) writestring
+      2 index /DA pget not { () } if
+      [ exch
+        { token {
+            dup /Tf eq {
+              2 index 0 eq {
+                /BBox load 3 get
+                0.75 mul   % empirical constant
+                4 -1 roll pop 3 1 roll
+              } if
+            } if
+            exch
+          } {
+            exit
+          } ifelse
+        } loop
+      ]
+      { 1 index exch write== } forall
+      dup 3 index /MaxLen pget not { 0 } if write=
+      dup 3 index /V pget not { () } if write==
+      dup 3 index /Ff pget not { 0 } if write=
+      dup 3 index /Q pget not { 0 } if write=
+      dup (Tform ET) write=
+      end
+      closefile             %  <acroform> <field> <annot>
+      dup 1 exch drawwidget
+    } if
+  } ifelse
+} bdef
+
+/Ch {
+  (Ch is not yet implemened) ==
+} bdef
+
+/Sig {
+  (Sig is not yet implemened ) ==
+} bdef
+
+currentdict end def
+
+/draw_terminal_field {   % <field> draw_terminal_field -
+ dup /Kids knownoget { 0 oget } { dup } ifelse
+ dup /P knownoget {
+    /Page load eq {
+      //draw_terminal_field_dict 2 index /FT pget not { 0 } if .knownget {
+        exec
+      } if
+   } if
+ } if
+ pop pop
+} bdef
+
+% We distinguish 4 types of nodes on the form field tree:
+%  - non-terminal field - has a kid that refers to the parent (or anywhere else)
+%  - terminal field with separate widget annotations - has a kid that doesn't have a parent
+%  - terminal field with a merged widget annotation - has no kids
+%  - widget annotation - has /Subtype and /Rect
+%
+% The recursive enumeration of the form fields doesn't descend into widget annotations.
+
+/draw_form_field { % <field> draw_form_field -
+  dup /Kids knownoget {                       % field []
+    dup 0 oget /Parent knownoget {            % field [] kid
+      pop % mon-terminal field                % field []
+      exch pop                                % []
+      { oforce draw_form_field } forall
+    } {
+      pop draw_terminal_field % separate annots % -
+    } ifelse
+  } {
+    draw_terminal_field % merged annotation   % -
+  } ifelse
+} bdef
+
+/draw_acro_form {		% <form> draw_acro_form -
+  dup /Fields knownoget {
+    { oforce draw_form_field } forall
+  } if
+  pop 
+} bdef
+
+currentdict /draw_terminal_field_dict undef
+
 end			% pdfdict
 end			% GS_PDF_ProcSet
 .setglobal

Modified: trunk/gs/lib/pdf_main.ps
===================================================================
--- trunk/gs/lib/pdf_main.ps	2007-04-23 21:46:19 UTC (rev 7877)
+++ trunk/gs/lib/pdf_main.ps	2007-04-23 23:59:01 UTC (rev 7878)
@@ -1325,6 +1325,7 @@
   grestore
   % Draw the annotations
   /Annots knownoget { { oforce drawannot } forall } if
+  Trailer /Root oget /AcroForm knownoget { draw_acro_form } if
 } bind def
 
 /processcolorspace {	% - processcolorspace <colorspace>

Modified: trunk/gs/lib/pdf_ops.ps
===================================================================
--- trunk/gs/lib/pdf_ops.ps	2007-04-23 21:46:19 UTC (rev 7877)
+++ trunk/gs/lib/pdf_ops.ps	2007-04-23 23:59:01 UTC (rev 7878)
@@ -695,6 +695,36 @@
 % within a single BT/ET pair, but it's a start.
 /tW { } bdef
 
+% Text formatting and painting for the AcroForm field without appearance streams.
+/Tform {                % <MaxLen> (V) <Ff> <Q> Tform -
+  clippath pathbbox 4 2 roll pop pop                        % MaxLen (V) Ff Q dx dy
+  currentfont /ScaleMatrix .knownget { 3 get } { 1 } ifelse % MaxLen (V) Ff Q dx dy yy
+  currentfont /FontBBox get dup 1 get neg exch 3 get        % MaxLen (V) Ff Q dx dy yy desc asc
+  dup 0 ne { div } { pop pop 0 } ifelse                     % MaxLen (V) Ff Q dx dy yy desc/asc
+  1 index mul                                               % MaxLen (V) Ff Q dx dy yy desc/asc*yy
+
+  4 index 16#1000 and 0 ne { % multiline
+    8 { pop } repeat (Multiline form fields are not yet implemented.) =
+  } {
+    4 index 16#1000000 and 0 ne { % comb
+      8 { pop } repeat (Combed form fields are not yet implemented.) =
+    } { % plain text                                       
+      3 1 roll sub add 2 div             % MaxLen (V) Ff Q dx (dy-yy+desc)/2
+      0 exch moveto                      % MaxLen (V) Ff Q dx
+      1 index 0 ne {
+        3 index stringwidth pop          % MaxLen (V) Ff Q dx w
+        sub exch 1 eq { 2 div } { 2 sub } ifelse % MaxLen (V) Ff (dx-w)/2
+        0 rmoveto                        % MaxLen (V) Ff
+        pop                              % MaxLen (V)
+      } {
+        pop pop pop                      % MaxLen (V)
+        2 0 rmoveto
+      } ifelse
+      exch pop Show                      % -
+    } ifelse
+  } ifelse
+} bdef
+
 end readonly put		% GS_PDF_ProcSet
 
 .setglobal



More information about the gs-cvs mailing list