Back to index

tetex-bin  3.0
magstep.c
Go to the documentation of this file.
00001 /* magstep.c: fix up fixed-point vs. floating-point.
00002 
00003 Copyright (C) 1994, 95 Karl Berry.
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Library General Public
00007 License as published by the Free Software Foundation; either
00008 version 2 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Library General Public License for more details.
00014 
00015 You should have received a copy of the GNU Library General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
00018 
00019 #include <kpathsea/config.h>
00020 
00021 #include <kpathsea/magstep.h>
00022 
00023 
00024 /* Return true magstep N, where the lsb of N means ``half'' (see
00025    magstep.h) for resolution BDPI.  From Tom Rokicki's dvips.  */
00026 
00027 static int
00028 magstep P2C(int, n,  int, bdpi)
00029 {
00030    double t;
00031    int step;
00032    int neg = 0;
00033 
00034    if (n < 0)
00035      {
00036        neg = 1;
00037        n = -n;
00038      }
00039 
00040    if (n & 1)
00041      {
00042        n &= ~1;
00043        t = 1.095445115;
00044      }
00045     else
00046       t = 1.0;
00047 
00048    while (n > 8)
00049      {
00050        n -= 8;
00051        t = t * 2.0736;
00052      }
00053 
00054    while (n > 0)
00055      {
00056        n -= 2;
00057        t = t * 1.2;
00058      }
00059 
00060    /* Unnecessary casts to shut up stupid compilers. */
00061    step = (int)(0.5 + (neg ? bdpi / t : bdpi * t));
00062    return step;
00063 }
00064 
00065 /* This is adapted from code written by Tom Rokicki for dvips.  It's
00066    part of Kpathsea now so all the drivers can use it.  The idea is to
00067    return the true dpi corresponding to DPI with a base resolution of
00068    BDPI.  If M_RET is non-null, we also set that to the mag value.  */
00069    
00070 /* Don't bother trying to use fabs or some other ``standard'' routine
00071    which can only cause trouble; just roll our own simple-minded
00072    absolute-value function that is all we need.  */
00073 #undef ABS /* be safe */
00074 #define ABS(expr) ((expr) < 0 ? -(expr) : (expr))
00075 
00076 #define MAGSTEP_MAX 40
00077 
00078 unsigned
00079 kpse_magstep_fix P3C(unsigned, dpi,  unsigned, bdpi,  int *, m_ret)
00080 {
00081   int m;
00082   int mdpi = -1;
00083   unsigned real_dpi = 0;
00084   int sign = dpi < bdpi ? -1 : 1; /* negative or positive magsteps? */
00085   
00086   for (m = 0; !real_dpi && m < MAGSTEP_MAX; m++) /* don't go forever */
00087     {
00088       mdpi = magstep (m * sign, bdpi);
00089       if (ABS (mdpi - (int) dpi) <= 1) /* if this magstep matches, quit */
00090         real_dpi = mdpi;
00091       else if ((mdpi - (int) dpi) * sign > 0) /* if gone too far, quit */
00092         real_dpi = dpi;
00093     }
00094   
00095   /* If requested, return the encoded magstep (the loop went one too far).  */
00096   /* More unnecessary casts. */
00097   if (m_ret)
00098     *m_ret = real_dpi == (unsigned)(mdpi ? (m - 1) * sign : 0);
00099 
00100   /* Always return the true dpi found.  */
00101   return real_dpi ? real_dpi : dpi;
00102 }