home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / TEKST / GROFFEXE / BIN / AFMTODIT.CMD < prev    next >
OS/2 REXX Batch file  |  1993-08-04  |  11KB  |  386 lines

  1. /* REXX conversion of AFMTODIT.CMD (Perl) by James Clark */
  2. /* Converted by Peter Flass <flass@lbdrscs> - July, 1993 */
  3. /* Requires Rexx math function package or equivalent     */
  4. /*          for sin() and cos() functions                */
  5.  
  6. Call RxFuncAdd "SysSearchPath" , "RexxUtil" , "SysSearchPath"
  7. Call RxFuncAdd "SysFileDelete" , "RexxUtil" , "SysFileDelete"
  8. Call RxFuncAdd "MathLoadFuncs" , "RxMathFn" , "MathLoadFuncs"
  9. rc = MathLoadFuncs()
  10.  
  11. Parse Arg args
  12. opt_s=''; opt_e=''; opt_i=''; opt_a='';
  13. argc = Words(args)
  14. opt_s = Wordpos("-s",args)
  15. If opt_s>0 Then args=Delword(args,opt_s,1)
  16. i = Wordpos("-e",args)
  17. If i>0 Then Do
  18.   opt_e = Word(args,i+1)
  19.   args  = Delword(args,i,2)
  20.   End
  21. i = Wordpos("-i",args)
  22. If i>0 Then Do
  23.   opt_i = Word(args,i+1)
  24.   args  = Delword(args,i,2)
  25.   End
  26. i = Wordpos("-a",args)
  27. If i>0 Then Do
  28.   opt_a = Word(args,i+1)
  29.   args  = Delword(args,i,2)
  30.   End
  31. If Words(args)<>3 Then Do
  32.    Say "Usage afmtodit [-s] [-e encoding] [-i n]",
  33.        " [-a angle] afmfile mapfile font"
  34.    Exit 
  35.    End
  36. Parse Var args afm map font
  37. /* Initialize stem variables */
  38. nmap.    = 0
  39. psname   = ''
  40. mapped.  = ''
  41. map.     = ''
  42. encoding.= ''
  43. height.  = 0
  44. depth.   = 0
  45. width.   = 0
  46.  
  47. kerns=0
  48. ligs=0
  49.  
  50. italic_angle=0
  51. italic_correction.=''
  52. left_italic_correction.=''
  53. char_space = "space"
  54. char_a     = 'a'
  55. char_alpha = "alpha"
  56. char_x     = 'x'
  57. TAB = X2C(09)
  58.  
  59. afm_file = afm
  60. If afm_file='' Then Do
  61.    Say "Can't open" afm
  62.    Exit
  63.    End
  64. Do While(lines(afm_file)>0)
  65.    inline=Linein(afm_file)
  66.    If Word(inline,1)="FontName" Then Do
  67.       psname=Word(inline,2)
  68.       End /* FontName */
  69.    Else If Word(inline,1)="ItalicAngle" Then Do
  70.       italic_angle=-Word(inline,2)
  71.       End /* ItalicAngle */
  72.    Else If Word(inline,1)="KPX" Then Do
  73.       If Words(inline)=4 Then Do
  74.          kerns=kerns+1
  75.          kern1.kerns=Word(inline,2)
  76.          kern2.kerns=Word(inline,3)
  77.          kernx.kerns=Word(inline,4)
  78.          End /* Words()=4 */
  79.       End /* KPX */
  80.    Else If Word(inline,1)="italicCorrection" Then Do
  81.       i=Word(inline,2)
  82.       italic_correction.i=Word(inline,3)
  83.       End /* italicCorrection */
  84.    Else If Word(inline,1)="leftItalicCorrection" Then Do
  85.       i=Word(inline,2)
  86.       left_italic_correction.i=Word(inline,3)
  87.       End /* left_italic_correction */
  88.    Else If Word(inline,1)="subscriptCorrection" Then Do
  89.       i=Word(inline,2)
  90.       subscript_correction.i=Word(inline,3)
  91.       End /* subscriptCorrection */
  92.    Else If Word(inline,1)="StartCharMetrics" Then Do
  93.       Call parse_char_metrics
  94.       End /* StartCharMetrics */
  95.    End /* Do While */
  96.  
  97. /* */
  98. /*      Read the DESC file                       */
  99.  
  100. desc_file = "DESC"
  101. If desc_file='' Then Do
  102.    Say "Can't open DESC"
  103.    Exit
  104.    End
  105. sizescale=1
  106. resolution=''; unitwidth=''; sizescale=''
  107. Do While(lines(desc_file)>0)
  108.    inline=Linein(desc_file)
  109.    If Substr(inline,1,1)='#' Then Iterate
  110.    If Word(inline,1)="charset" Then Leave
  111.    If Word(inline,1)="res" 
  112.    Then resolution=Word(inline,2)
  113.    If Word(inline,1)="unitwidth" 
  114.    Then unitwidth=Word(inline,2)
  115.    If Word(inline,1)="sizescale" 
  116.    Then sizescale=Word(inline,2)
  117.    End /* Do While */
  118.  
  119. /*      Read the encoding file                */
  120. If opt_e<>'' Then Do
  121.    encoding_file = opt_e
  122.    If encoding_file='' Then Do
  123.       Say "Can't open" opt_e
  124.       Exit
  125.       End
  126.    Do While(Lines(encoding_file)>0)
  127.       inline=Linein(encoding_file)
  128.       If Words(inline)=2 Then Do
  129.          field0=Word(inline,1)
  130.          field1=Word(inline,2)
  131.          If field1>=0 & width.field0<>'' Then Do
  132.             encoding.field1=field0
  133.             in_encoding.field0=1
  134.             End  /* If */
  135.          End /*Words=2 */
  136.       End /* Do While */
  137.    End /* opt_e */
  138.  
  139. /*      Read the map file                        */
  140. map_file = map
  141. If map_file='' Then Do
  142.    Say "Can't open" map
  143.    Exit
  144.    End
  145. Do While(lines(map_file)>0)
  146.    inline=Linein(map_file)
  147.    If Substr(inline,1,1)='#' Then Iterate
  148.    field0=Word(inline,1)
  149.    field1=Word(inline,2)
  150.    If Words(inline)=2 & in_encoding.field0=1 Then Do
  151.         If mapped.field1<>''
  152.         Then Say "Both" mapped.field1 "and" field0 "map to" field1
  153.         Else If field1 = "space"
  154.         /* The PostScript character 'space' is automatically mapped */
  155.         /* to the groff character 'space'; this is for grops        */
  156.            Then Say "you are not allowed to map" ,
  157.                     "the Postscript character `space'"
  158.            Else Do
  159.               map.field0   = map.field0 field1
  160.               nmap.field0  = nmap.field0+1
  161.               mapped.field1= field0
  162.               End /* Else */
  163.       End /* If Words */
  164.    End /* Do While */
  165.  
  166. if opt_a<>'' Then italic_angle=opt_a
  167.  
  168. /* */
  169. /*----------------------------------------------------*/
  170. /*        Print it all out                            */
  171. /*----------------------------------------------------*/
  172.  
  173. x = SysFileDelete(font)
  174. If x>2 Then Do
  175.    Say "Can't open" font "for output"
  176.    Exit
  177.    End
  178. x = Lineout(font,"name" font)
  179. x = Lineout(font,"internalname" psname)
  180. If opt_s<>0        Then x = Lineout(font,"special")
  181. if italic_angle<>0 Then x = Lineout(font,"slant" italic_angle)
  182. If width.char_space <> ''
  183. Then x = Lineout(font,"spacewidth",
  184.                  Conv(width.char_space))
  185. If opt_e<>'' Then x = Lineout(font,"encoding" opt_e)
  186.  
  187. If ligs>0 Then Do
  188.    l=''
  189.    x = Lineout(font,"ligatures")
  190.    Do i=1 To ligs
  191.       l = l ligature.i
  192.       End /* Do */
  193.    l = l "0"
  194.    x = Lineout(font,l)
  195.    End /* ligs>0 */
  196.  
  197. If kerns>0 Then Do
  198.    x = Lineout(font,"kernpairs")
  199.    Do i=1 To kerns
  200.       c1=kern1.i
  201.       c2=kern2.i
  202.       if in_encoding.c1=1 & nmap.c1<>0 & ,
  203.          in_encoding.c2=1 & nmap.c2<>0 Then Do
  204.          Do j=1 To nmap.c1
  205.             Do k=1 to nmap.c2
  206.                x = Lineout(font,Word(map.c1,j) Word(map.c2,k) ,
  207.                                 Conv(kernx.i))
  208.                End /* Do k */
  209.             End /* Do j */
  210.          End /* in_encoding */
  211.       End /* Do i */
  212.    End /* kerns */
  213.  
  214. /* Characters taller than asc_boundary are considered to have ascenders */
  215. asc_boundary = height.char_a + 50
  216. /* likewise for descenders */
  217. desc_boundary = depth.char_a + 50
  218. If height.char_x <> "HEIGHT.x"
  219. Then xheight = height.char_x
  220. Else If height.char_alpha <> "HEIGHT.alpha"
  221.      Then xheight = height.char_alpha
  222.      Else xheight = 450
  223.  
  224. /* Convert degrees to radians */
  225. italic_angle = italic_angle * 3.14159265358979323846 / 180
  226. slant        = Sin(italic_angle) / Cos(italic_angle)
  227. If slant<0 Then slant=0
  228.  
  229. x = Lineout(font,"charset")
  230. Do i=1 to 256
  231.    ch=encoding.i
  232.    l=''
  233.    If ch<>'' & ch<>"space" Then Do
  234.       If nmap.ch=0 Then map.ch="---"
  235.       type=0
  236.       h=height.ch
  237.       If h<0 Then h=0
  238.       d=depth.ch
  239.       if d<0 Then d=0
  240.       If d>desc_boundary Then type=1
  241.       If h>asc_boundary  Then type=type+2
  242.       l = Word(map.ch,1)||TAB||Conv(width.ch)
  243.       italic_correction=0
  244.       left_math_fit=0
  245.       subscript_correction=0
  246.       If opt_i<>'' Then Do
  247.          italic_correction = right_side_bearing.ch + opt_i
  248.          If italic_correction<0 Then italic_correction=0
  249.          subscript_correction = slant * xheight * .8
  250.          If subscript_correction>italic_correction 
  251.          Then subscript_correction = italic_correction
  252.          left_math_fit = left_side_bearing.ch + opt_i
  253.          End /* opt_i */
  254.       If italic_correction.ch <> ''
  255.       Then italic_correction = italic_correction.ch
  256.       If left_italic_correction.ch <> ''
  257.       Then left_math_fit = left_italic_correction.ch
  258.       If subscript_correction <> 0 Then Do
  259.          l = l||','||Conv(h)||','||Conv(d)
  260.          l = l||','||Conv(italic_correction),
  261.               ||','||Conv(left_math_fit),
  262.               ||','||Conv(subscript_correction)
  263.          End /* subscript_correction */
  264.       Else If left_math_fit <> 0 Then Do
  265.          l = l||','||Conv(h)||','||Conv(d)
  266.          l = l||','||Conv(italic_correction),
  267.               ||','||Conv(left_math_fit)||TAB
  268.          End /* left_math_fit */
  269.       Else If italic_correction <> 0 Then Do
  270.          l = l||','||Conv(h)||','||Conv(d)
  271.          l = l||','||Conv(italic_correction)||TAB
  272.          End /* italic_correction */
  273.       Else If d <> 0 Then Do
  274.          l = l||','||Conv(h)||','||Conv(d)||TAB||TAB
  275.          End /* d<>0 */
  276.       Else Do
  277.          /* Always put the height in to stop groff guessing */
  278.          l = l||','||Conv(h)||TAB||TAB
  279.          End /* otherwise */
  280.       l = l || TAB || type
  281.       l = l || TAB || '0'Oct(i) || TAB || ch
  282.       x=Lineout(font,l)
  283.       Do j=2 To nmap.ch
  284.          l = Word(map.ch,j) || TAB || '"'
  285.          x = Lineout(font,l)
  286.          End /* Do j */
  287.       If ch="space" & width.char_space <> '' Then Do
  288.          x = Lineout(font,"space"||TAB||conv(width.char_space)||,
  289.                           TAB||'0'||TAB||'0'Oct(i))
  290.          End /* space */
  291.       End /* <> space */
  292.    End /* Do i */
  293.  
  294. Exit
  295.  
  296. /* Convert height and width to device units */
  297. Conv:
  298.    Parse Arg num
  299.    If num='' Then num=0
  300.    If num<0 Then adj=-.5; Else adj=.5
  301.    Return Trunc( num * unitwidth * resolution / ,
  302.                 (72*1000*sizescale) + adj )
  303. /* End Conv       */
  304.  
  305. /* */
  306. /*----------------------------------------------------*/
  307. /*      Process Character metrics from AFM file       */
  308. /*----------------------------------------------------*/
  309. parse_char_metrics:
  310.   Do While(lines(afm_file)>0)
  311.      inline=Linein(afm_file)
  312.      If Word(inline,1)="EndCharMetrics" Then Return
  313.      If Word(inline,1)="C" Then Do
  314.         c  = -1
  315.         wx = 0
  316.         n  = ''
  317.         lly=0; ury=0
  318.         llx=0; urx=0
  319.         c  = Word(inline,2)
  320.         i=3
  321.         Do While(i<=Words(inline))
  322.            If Word(inline,i)="WX" Then Do
  323.               w=Word(inline,i+1)
  324.               i=i+2
  325.               End /* WX */
  326.            Else If Word(inline,i)="N" Then Do
  327.               n=Word(inline,i+1)
  328.               i=i+2;
  329.               End /* N */
  330.            Else If Word(inline,i)="B" Then Do
  331.               llx=Word(inline,i+1)
  332.               lly=Word(inline,i+2)
  333.               urx=Word(inline,i+3)
  334.               ury=Word(inline,i+4)
  335.               i=i+5
  336.               End /* B */
  337.            Else If Word(inline,i)="L" Then Do
  338.               ligs=ligs+1
  339.               ligatures.ligs=Word(inline,i+2)
  340.               i=i+3;
  341.               End /* L */
  342.            Else Do 
  343.               Do While(i<=Words(inline) & ,
  344.                        Word(inline,i)<>';')
  345.                  i=i+1;
  346.                  End /* Do While */
  347.               i=i+1
  348.               End /* Else */
  349.            End /* Do While */
  350.  
  351.         encoding.c=''
  352.         in_encoding.c=0
  353.         If opt_e='' & c<>"-1" Then Do
  354.            encoding.c=n
  355.            in_encoding.n=1
  356.            End /* opt_e */
  357.  
  358.         width.n  = w
  359.         height.n = ury
  360.         depth.n  = -lly
  361.         left_side_bearing.n  = -llx
  362.         right_side_bearing.n = urx-w
  363.         nmap.n   = 0
  364.         map.n    = ''
  365.  
  366.         End /* C */
  367.  
  368.      End /* Do While */
  369.    Return
  370. /* End parse_char_metrics */
  371.  
  372. /*   Convert arg to 3 octal digits */
  373. Oct: Procedure
  374.    Parse Arg num
  375.    o=''
  376.    Do i=1 To 3
  377.       z   = Trunc(num/8)
  378.       d   = num-z*8
  379.       o   = d||o
  380.       num = z
  381.       End /* Do */
  382.    Return o
  383. /* End Oct        */
  384.  
  385.  
  386.