home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / dvips / papersiz.c < prev    next >
C/C++ Source or Header  |  1994-03-29  |  3KB  |  131 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. #ifdef AMIGA
  16. #include "papersiz_protos.h"
  17. #include "dvips_protos.h"
  18. static long scale(long,long,long,long);
  19. static long myatol(char **);
  20. #else
  21. void error() ;
  22. #endif
  23. static long scale(whole, num, den, sf)
  24. long whole, num, den, sf ;
  25. {
  26.    long v ;
  27.  
  28.    v = whole * sf + num * (sf / den) ;
  29.    if (v / sf != whole || v < 0 || v > 0x40000000L)
  30.       error("! arithmetic overflow in parameter") ;
  31.    sf = sf % den ;
  32.    v += (sf * num * 2 + den) / (2 * den) ;
  33.    return(v) ;
  34. }
  35. /*
  36.  *   Convert a sequence of digits into a long; return -1 if no digits.
  37.  *   Advance the passed pointer as well.
  38.  */
  39. static long myatol(s)
  40. char **s ;
  41. {
  42.    register char *p ;
  43.    register long result ;
  44.  
  45.    result = 0 ;
  46.    p = *s ;
  47.    while ('0' <= *p && *p <= '9') {
  48.       if (result > 100000000)
  49.          error("! arithmetic overflow in parameter") ;
  50.       result = 10 * result + *p++ - '0' ;
  51.    }
  52.    if (p == *s) {
  53.       error("expected number!  returning 10") ;
  54.       return 10 ;
  55.    } else {
  56.       *s = p ;
  57.       return(result) ;
  58.    }
  59. }
  60. /*
  61.  *   Get a dimension, allowing all the various extensions, and
  62.  *   defaults.  Returns a value in scaled points.
  63.  */
  64. static long scalevals[] = { 1864680L, 65536L, 786432L, 186468L,
  65.                             1L, 65782L, 70124L, 841489L, 4736286L } ;
  66. static char *scalenames = "cmptpcmmspbpddccin" ;
  67. long myatodim(s)
  68. char **s ;
  69. {
  70.    register long w, num, den, sc ;
  71.    register char *q ;
  72.    char *p ;
  73.    int negative = 0, i ;
  74.  
  75.    p = *s ;
  76.    if (**s == '-') {
  77.       p++ ;
  78.       negative = 1 ;
  79.    }
  80.    w = myatol(&p) ;
  81.    if (w < 0) {
  82.       error("number too large; 1000 used") ;
  83.       w = 1000 ;
  84.    }
  85.    num = 0 ;
  86.    den = 1 ;
  87.    if (*p == '.') {
  88.       p++ ;
  89.       while ('0' <= *p && *p <= '9') {
  90.          if (den <= 1000) {
  91.             den *= 10 ;
  92.             num = num * 10 + *p - '0' ;
  93.          } else if (den == 10000) {
  94.             den *= 2 ;
  95.             num = num * 2 + (*p - '0') / 5 ;
  96.          }
  97.          p++ ;
  98.       }
  99.    }
  100.    while (*p == ' ')
  101.       p++ ;
  102.    for (i=0, q=scalenames; ; i++, q += 2)
  103.       if (*q == 0) {
  104.          error("expected units!  assuming inches.") ;
  105.          sc = scalevals[8] ;
  106.          break ;
  107.       } else if (*p == *q && p[1] == q[1]) {
  108.          sc = scalevals[i] ;
  109.          p += 2 ;
  110.          break ;
  111.       }
  112.    w = scale(w, num, den, sc) ;
  113.    *s = p ;
  114.    return(negative?-w:w) ;
  115. }
  116. /*
  117.  *   The routine where we handle the paper size special.  We need to pass in
  118.  *   the string after the `papersize=' specification.
  119.  */
  120. void handlepapersize(p, x, y)
  121. char *p ;
  122. integer *x, *y ;
  123.    while (*p == ' ')
  124.       p++ ;
  125.    *x = myatodim(&p) ;
  126.    while (*p == ' ' || *p == ',')
  127.       p++ ;
  128.    *y = myatodim(&p) ;
  129. }
  130.