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

alexcher at ghostscript.com alexcher at ghostscript.com
Mon Apr 9 13:50:20 PDT 2007


Author: alexcher
Date: 2007-04-09 13:50:20 -0700 (Mon, 09 Apr 2007)
New Revision: 7838

Modified:
   trunk/gs/lib/pdf2dsc.ps
Log:
Interpret PDF PageLabels dictionary and include the labels in %%Page comments
in the PS file. Thanks to Jason McCarty for the patch. Bug 688071.


Modified: trunk/gs/lib/pdf2dsc.ps
===================================================================
--- trunk/gs/lib/pdf2dsc.ps	2007-04-09 08:54:30 UTC (rev 7837)
+++ trunk/gs/lib/pdf2dsc.ps	2007-04-09 20:50:20 UTC (rev 7838)
@@ -25,6 +25,8 @@
 % Then display the PDF file with
 %  gs tempfilename
 %
+% Modified by Jason McCarty, bug 688071
+%       Add PageLabels support.
 % Modified by Geoff Keating <geoffk at ozemail.com.au> 21/12/98:
 %	Add DocumentMedia, PageMedia comments
 %	Use inherited BoundingBox and Orientation
@@ -51,14 +53,6 @@
 /DSCstring 255 string def
 /MediaTypes 10 dict def
 
-% (str1) (str2)  concatstr  (str1str2)
-/concatstr {
-  2 copy length exch length add string
-  dup dup 5 2 roll copy length
-% stack: newstring newstring str2 str1-length
-  exch putinterval
-} bind def
-
    GS_PDF_ProcSet begin
    pdfdict begin
    PDFfile
@@ -73,7 +67,7 @@
       3 -1 roll sub 3 1 roll exch sub exch
       2 array astore 
       aload 3 1 roll 10 string cvs exch 10 string cvs
-      (x) exch concatstr concatstr cvn
+      (x) 3 -1 roll concatstrings concatstrings cvn
       MediaTypes 3 1 roll exch put
    } for
 
@@ -123,10 +117,101 @@
    ( \(r\) file { DELAYSAFER { .setsafe } if } stopped pop\n) puts
    ( pdfopen begin\n) puts
    (%%EndSetup\n) puts
+
+   /.hasPageLabels false def % see "Page Labels" in the PDF Reference
+   Trailer /Root knownoget {
+     /PageLabels knownoget {
+       /PageLabels exch def
+       /.pageCounter 1 def
+       /.pageCounterType /D def
+       /.pagePrefix () def
+
+       % (TEXT)  .ToLower  (text)  -- convert text to lowercase -- only letters!
+       /.ToLower {
+         dup length 1 sub  -1 0 {
+           1 index exch 2 copy get 2#00100000 or put
+         } for
+       } def
+
+       % int  .CvAlpha  (int in alphabetic base 26)  -- convert a positive
+       % integer to base 26 in capital letters, with 1=A; i.e. A..Z, AA..AZ, ...
+       /.CvAlpha { % using cvrs seems futile since this isn't zero-based ...
+         [ exch % construct an array of ASCII values, in reverse
+         { % the remainder stays on the top of stack
+           dup 0 eq { pop exit } if % quit if the value is zero
+           dup 26 mod dup 0 eq { 26 add } if % so that the division is correct
+           dup 64 add 3 1 roll sub 26 idiv % save the ASCII value and iterate
+         } loop ]
+         dup length dup string 3 1 roll
+         dup -1 1 { % put the letters in a string
+           4 copy sub exch 4 -1 roll 1 sub get put
+         } for pop pop
+       } def
+
+       % int  .CvRoman  (int in capital Roman numerals)
+       % convert a positive integer to capital Roman numerals
+       % return a decimal string if >= 4000
+       /.CvRoman {
+         dup DSCstring cvs % start with the decimal representation
+         exch 4000 lt { % convert only if Roman numerals can represent this
+           dup length
+           [ [ () (I) (II) (III) (IV) (V) (VI) (VII) (VIII) (IX) ]
+             [ () (X) (XX) (XXX) (XL) (L) (LX) (LXX) (LXXX) (XC) ]
+             [ () (C) (CC) (CCC) (CD) (D) (DC) (DCC) (DCCC) (CM) ]
+             [ () (M) (MM) (MMM) ] ] % Roman equivalents
+           () % append the Roman equivalent of each decimal digit to this string
+           2 index  -1 1 {
+             2 index 1 index 1 sub get
+             5 index 5 index 4 -1 roll sub get
+             48 sub get concatstrings
+           } for
+           4 1 roll pop pop pop
+         } if
+       } def
+
+       /PageToString <<
+         /D { DSCstring cvs }
+         /R { .CvRoman }
+         /r { .CvRoman .ToLower }
+         /A { .CvAlpha }
+         /a { .CvAlpha .ToLower }
+       >> def
+       /.hasPageLabels true def
+     } if
+   } if
+
    % process each page
    FirstPage 1 LastPage {
        (%%Page: ) puts
-       dup DSCstring cvs puts
+
+       .hasPageLabels {
+         dup 1 sub PageLabels exch numoget dup null ne {
+           % page labels changed at this page, reset the values
+           dup /S known { dup /S get } { null } ifelse
+           /.pageCounterType exch def
+
+           dup /P known { dup /P get } { () } ifelse
+           /.pagePrefix exch def
+
+           dup /St known { /St get } { pop 1 } ifelse
+           /.pageCounter exch def
+         } { pop } ifelse
+
+         % output the page label
+         (\() .pagePrefix
+         PageToString .pageCounterType known { % format the page number
+           .pageCounter dup 0 gt { % don't try to format nonpositive numbers
+             PageToString .pageCounterType get exec
+           } {
+             DSCstring cvs
+          } ifelse
+         } { () } ifelse
+         (\)) concatstrings concatstrings concatstrings puts
+
+         /.pageCounter .pageCounter 1 add def
+       } {
+         dup DSCstring cvs puts
+       } ifelse
        ( ) puts
        dup DSCstring cvs puts
        (\n) puts



More information about the gs-cvs mailing list