summaryrefslogtreecommitdiff
path: root/Build/source/texk/kpathsea/magstep.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/kpathsea/magstep.c')
-rw-r--r--Build/source/texk/kpathsea/magstep.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/Build/source/texk/kpathsea/magstep.c b/Build/source/texk/kpathsea/magstep.c
new file mode 100644
index 00000000000..95a16ba5d7c
--- /dev/null
+++ b/Build/source/texk/kpathsea/magstep.c
@@ -0,0 +1,112 @@
+/* magstep.c: fix up fixed-point vs. floating-point.
+
+ Copyright 1994, 1995, 2008 Karl Berry.
+ Copyright 1999, 2005 Olaf Weber.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, see <http://www.gnu.org/licenses/>. */
+
+#include <kpathsea/config.h>
+
+#include <kpathsea/magstep.h>
+
+/* Return true magstep N, where the lsb of N means ``half'' (see
+ magstep.h) for resolution BDPI. From Tom Rokicki's dvips. */
+
+static int
+magstep (int n, int bdpi)
+{
+ double t;
+ int step;
+ int neg = 0;
+
+ if (n < 0)
+ {
+ neg = 1;
+ n = -n;
+ }
+
+ if (n & 1)
+ {
+ n &= ~1;
+ t = 1.095445115;
+ }
+ else
+ t = 1.0;
+
+ while (n > 8)
+ {
+ n -= 8;
+ t = t * 2.0736;
+ }
+
+ while (n > 0)
+ {
+ n -= 2;
+ t = t * 1.2;
+ }
+
+ /* Unnecessary casts to shut up stupid compilers. */
+ step = (int)(0.5 + (neg ? bdpi / t : bdpi * t));
+ return step;
+}
+
+/* This is adapted from code written by Tom Rokicki for dvips. It's
+ part of Kpathsea now so all the drivers can use it. The idea is to
+ return the true dpi corresponding to DPI with a base resolution of
+ BDPI. If M_RET is non-null, we also set that to the mag value. */
+
+
+/* Don't bother trying to use fabs or some other ``standard'' routine
+ which can only cause trouble; just roll our own simple-minded
+ absolute-value function that is all we need. */
+#undef ABS /* be safe */
+#define ABS(expr) ((expr) < 0 ? -(expr) : (expr))
+
+#define MAGSTEP_MAX 40
+
+unsigned
+kpathsea_magstep_fix (kpathsea kpse, unsigned dpi, unsigned bdpi, int *m_ret)
+{
+ int m;
+ int mdpi = -1;
+ unsigned real_dpi = 0;
+ int sign = dpi < bdpi ? -1 : 1; /* negative or positive magsteps? */
+ (void)kpse; /* currenty not used */
+
+ for (m = 0; !real_dpi && m < MAGSTEP_MAX; m++) /* don't go forever */
+ {
+ mdpi = magstep (m * sign, bdpi);
+ if (ABS (mdpi - (int) dpi) <= 1) /* if this magstep matches, quit */
+ real_dpi = mdpi;
+ else if ((mdpi - (int) dpi) * sign > 0) /* if gone too far, quit */
+ real_dpi = dpi;
+ }
+
+ /* If requested, return the encoded magstep (the loop went one too far). */
+ /* More unnecessary casts. */
+ if (m_ret)
+ *m_ret = real_dpi == (unsigned)(mdpi ? (m - 1) * sign : 0);
+
+ /* Always return the true dpi found. */
+ return real_dpi ? real_dpi : dpi;
+}
+
+#if defined (KPSE_COMPAT_API)
+unsigned
+kpse_magstep_fix (unsigned dpi, unsigned bdpi, int *m_ret)
+{
+ return kpathsea_magstep_fix(kpse_def, dpi, bdpi, m_ret);
+}
+#endif
+