    ! EDWIN PDF DECODE PROGRAM

    external string(31) Version   = "5",
                          Release   = "1",
                          Revision  = "0",
                          Fname     = "PDFDEC",
                       Product Code = "PDFDEC"

    from Imp include Cliparse
    from LL  include Common

    begin
    own integer XL = 0;        !Origin of virtual window (Left edge)
    own integer XR = 1023;     !(Right edge)
    own integer YB = 0;        !(Bottom edge)
    own integer YT = 1023;     !(Top edge)
    own integer A, B

    const string (15) array COM (0:15) = "Line abs", "Move abs", "Marker abs",
       "Line rel", "Move rel", "Marker rel", "Polygon", "Elipse", "Window",
       "Character", "", "Newframe", "Terminate EDWIN", "Rectangle", "Circle", ""

    const string (23) array ATT (0:15) =   "Set colour",  "Set line style",
     "Set char size",  "Set char rot",  "Set char quality",  "Set char font",
     "Set char slant", "Set intensity", "Set speed",         "Set colour mode",
     "Set shade mode", "Set chord step","Set char mirror",   "Set polygon mode",
     "Set unknown att", "Aspect ratioing"

    routine PHEX (integer I)
       const byte integer array A(0:15) = '0', '1', '2', '3', '4',
        '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
       integer L

       SPACE
       for L=12,-4,0 cycle
            PRINT SYMBOL (A(I>>L&15))
       repeat
    end

    routine INTERPRET
       ! PC=0 => PDF read from the input stream, else read from the array.
       !Interpret instructions in display file starting
       !at (relative) PC until an END instruction is found
       !For more information on display file layout, see GRAFIX.PDFDOC.
       !Codes are   0 LINEA   1 MOVEA   2 MARKERA
       !            3 LINER   4 MOVER   5 MARKERR
       !            6 SUBPIC  7 old END 8 WINDOW
       !            9 CHAR   10 ATTRIBUTES  11  NEWFRAME   12  END
       integer WORD,CODE,X,Y,WX, WY
       switch C(0:15)

       cycle
          read (WORD)
          CODE=WORD&15
          if CODE<=5 start;    !Draw, Move, Point
              read(X)
              A = X
              if WORD&16=0 start;   !Long form
                  read(Y)
              finishelse start
                  Y=X&255; X=X>>8&255
                  X=X!!(¬255) if X&128#0
                  Y=Y!!(¬255) if Y&128#0
              finish
        finish
        ->C(CODE)

    C(0): C(1): C(2): C(3): C(4): C(5): ! MOVE LINE and MARKERs
          PHEX (WORD)
          PHEX (A)
          if WORD&16=0 then PHEX (Y) else SPACES (5)
          SPACES (20)
          PRINT STRING (COM(CODE)." (")
          WRITE (WORD>>12&15,0) and PRINT STRING (", ") if CODE=2 or CODE=5
          WRITE (X,0);   PRINT SYMBOL (',')
          WRITE (Y,1);   PRINT SYMBOL (')')
          NEWLINE
          continue

    C(8): ! SET new WINDOW
          read(XL);  read(XR);  read(CODE);  read (YB);  read (YT)
          PHEX (WORD);  PHEX (XL);  PHEX (XR);  PHEX (CODE);  PHEX (YB);  PHEX (YT)
          SPACES (5)
          PRINT STRING (COM(8)." (")
          WRITE (XL,0);   PRINT SYMBOL (',')
          WRITE (XR,1);   PRINT SYMBOL (',')
          WRITE (YB,1);   PRINT SYMBOL (',')
          WRITE (YT,1);   PRINT SYMBOL (')')
          NEWLINE
          continue

    C(9): ! Character
    C(11): ! Newframe
    C(12): ! Terminate
          PHEX (WORD)
          SPACES (30)
          PRINT STRING (COM(CODE))
          if CODE=9 start
              PRINT STRING (" (")
              A = WORD >> 4
              if 32<= A <= 127 start
                  PRINT SYMBOL ('''')
                  PRINT SYMBOL (A)
                  PRINT SYMBOL ('''')
              finish else WRITE (A,0)
              PRINT SYMBOL (')')
          finish
          NEWLINE
          continue

    C(15):
    C(10): if CODE=10 then A=WORD>>4&255 else read(A)
           B = WORD >> 12 & 15
           PHEX (WORD)
           if CODE=10 then SPACES(5) else PHEX (A)
           SPACES (25)
           PRINT STRING (COM(CODE).ATT(B)." (".ItoS(A,0).")")
           NEWLINE
           continue

    C(6):  ! Polygon
           READ (WX)
           PHEX (WORD)
           SPACES (30)
           PRINT STRING ("! Polygon with ".ItoS(WX,0)." sides")
           NEWLINE
           for WY = 1, 1, WX cycle
                READ (X);   READ (Y)
           repeat
           continue

    C(13): ! Rectangle
           READ (WX);   READ (WY);   READ (CODE);   READ (X);   READ (Y)
           PHEX (WORD)
           PHEX (WX);   PHEX (WY);   PHEX (CODE);   PHEX (X);   PHEX (Y)
           SPACES (5)
           PRINT STRING (COM(CODE)." (")
           WRITE (WX,0);   PRINT STRING (", ")
           WRITE (WY,0);   PRINT STRING (", ")
           WRITE (X,0);   PRINT STRING (", ")
           WRITE (Y,0);   PRINT SYMBOL (')')
           NEWLINE
           continue

    C(14): !Circle
           READ (X)
           PHEX (WORD)
           SPACES (30)
           PRINT STRING (COM(CODE)." (".ItoS(X,0).")")
           NEWLINE
           continue

      repeat

    C(*): PHEX (WORD)
          SPACES (30)
          PRINT STRING ("Unknown PDF command")
          NEWLINE
          PRINT STRING ("******   ANALYSIS  ABANDONED  *******")
          NEWLINE
          Fatal Error ("Analysis abandoned on unknown PDF command")
    end

       string (255) In file, Out file

       on 3,4,9 start
          if EVENT_EVENT # 9 start
              Fatal Error ("Corrupt PDF")
          finish
          stop
       finish

        if Qualifier Present("IDENTIFY") start
           Print Identification
           return unless Qualifier Present("FILE")
        finish

       In File = Qualifier S ("FILE")
       Out File = Qualifier S ("OUTPUT")
       Open LL Input (1, LL EDWIN PDF File, 0, In File, "")
       if Out file # "" start
           Open LL Output (2, LL Listing File, 0, Out file, "")
           Select output (2)
       else
           Select output (0)
       finish
       Prompt ("PDF data: ")
       Interpret
    end of program