home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fonts 1 / freshfonts1.bin / bbs / programs / amiga / pastex13.lha / DVIPS / dvips5519.lha / dvips / papersiz.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  3KB  |  124 lines

  1. /*
  2.  *   This function calculates approximately (whole + num/den) * sf.
  3.  *   No need for real extreme accuracy; one twenty thousandth of an
  4.  *   inch should be sufficient.
  5.  *
  6.  *   No `sf' parameter means to use an old one; inches are assumed
  7.  *   originally.
  8.  *
  9.  *   Assumptions:
  10.  *
  11.  *      0 <= num < den <= 20000
  12.  *      0 <= whole
  13.  */
  14. #include "dvips.h"
  15. void error() ;
  16. static long scale(whole, num, den, sf)
  17. long whole, num, den, sf ;
  18. {
  19.    long v ;
  20.  
  21.    v = whole * sf + num * (sf / den) ;
  22.    if (v / sf != whole || v < 0 || v > 0x40000000L)
  23.       error("! arithmetic overflow in parameter") ;
  24.    sf = sf % den ;
  25.    v += (sf * num * 2 + den) / (2 * den) ;
  26.    return(v) ;
  27. }
  28. /*
  29.  *   Convert a sequence of digits into a long; return -1 if no digits.
  30.  *   Advance the passed pointer as well.
  31.  */
  32. static long myatol(s)
  33. char **s ;
  34. {
  35.    register char *p ;
  36.    register long result ;
  37.  
  38.    result = 0 ;
  39.    p = *s ;
  40.    while ('0' <= *p && *p <= '9') {
  41.       if (result > 100000000)
  42.          error("! arithmetic overflow in parameter") ;
  43.       result = 10 * result + *p++ - '0' ;
  44.    }
  45.    if (p == *s) {
  46.       error("expected number!  returning 10") ;
  47.       return 10 ;
  48.    } else {
  49.       *s = p ;
  50.       return(result) ;
  51.    }
  52. }
  53. /*
  54.  *   Get a dimension, allowing all the various extensions, and
  55.  *   defaults.  Returns a value in scaled points.
  56.  */
  57. static long scalevals[] = { 1864680L, 65536L, 786432L, 186468L,
  58.                             1L, 65782L, 70124L, 841489L, 4736286L } ;
  59. static char *scalenames = "cmptpcmmspbpddccin" ;
  60. long myatodim(s)
  61. char **s ;
  62. {
  63.    register long w, num, den, sc ;
  64.    register char *q ;
  65.    char *p ;
  66.    int negative = 0, i ;
  67.  
  68.    p = *s ;
  69.    if (**s == '-') {
  70.       p++ ;
  71.       negative = 1 ;
  72.    }
  73.    w = myatol(&p) ;
  74.    if (w < 0) {
  75.       error("number too large; 1000 used") ;
  76.       w = 1000 ;
  77.    }
  78.    num = 0 ;
  79.    den = 1 ;
  80.    if (*p == '.') {
  81.       p++ ;
  82.       while ('0' <= *p && *p <= '9') {
  83.          if (den <= 1000) {
  84.             den *= 10 ;
  85.             num = num * 10 + *p - '0' ;
  86.          } else if (den == 10000) {
  87.             den *= 2 ;
  88.             num = num * 2 + (*p - '0') / 5 ;
  89.          }
  90.          p++ ;
  91.       }
  92.    }
  93.    while (*p == ' ')
  94.       p++ ;
  95.    for (i=0, q=scalenames; ; i++, q += 2)
  96.       if (*q == 0) {
  97.          error("expected units!  assuming inches.") ;
  98.          sc = scalevals[8] ;
  99.          break ;
  100.       } else if (*p == *q && p[1] == q[1]) {
  101.          sc = scalevals[i] ;
  102.          p += 2 ;
  103.          break ;
  104.       }
  105.    w = scale(w, num, den, sc) ;
  106.    *s = p ;
  107.    return(negative?-w:w) ;
  108. }
  109. /*
  110.  *   The routine where we handle the paper size special.  We need to pass in
  111.  *   the string after the `papersize=' specification.
  112.  */
  113. void handlepapersize(p, x, y)
  114. char *p ;
  115. integer *x, *y ;
  116.    while (*p == ' ')
  117.       p++ ;
  118.    *x = myatodim(&p) ;
  119.    while (*p == ' ' || *p == ',')
  120.       p++ ;
  121.    *y = myatodim(&p) ;
  122. }
  123.