diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/seetexk/scaletfm.c | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/seetexk/scaletfm.c')
-rw-r--r-- | Build/source/texk/seetexk/scaletfm.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/Build/source/texk/seetexk/scaletfm.c b/Build/source/texk/seetexk/scaletfm.c new file mode 100644 index 00000000000..f6444d5d369 --- /dev/null +++ b/Build/source/texk/seetexk/scaletfm.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1987, 1989 University of Maryland + * Department of Computer Science. All rights reserved. + * Permission to copy for any purpose is hereby granted + * so long as this copyright notice remains intact. + */ + +#ifndef lint +static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/scaletfm.c,v 3.2 89/11/23 16:34:43 chris Exp $"; +#endif + +#include "types.h" +#include "error.h" +#include "font.h" + +/* + * From DVITYPE.WEB: + * + * ``The most important part of in_TFM is the width computation, which + * involvles multiplying the relative widths in the TFM file by the scaling + * factor in the DVI file. This fixed-point multiplication must be done with + * precisely the same accuracy by all DVI-reading programs, in order to + * validate the assumptions made by DVI-writing programs like \TeX 82. + * + * Let us therefore summarize what needs to be done. Each width in a TFM + * file appears as a four-byte quantity called a fix_word. A fix_word whose + * respective bytes are (a,b,c,d) represents the number + * + * {{ b * 2^{-4} + c * 2^{-12} + d * 2^{-20}, if a = 0; + * x = {{ + * {{ -16 + b * 2^{-4} + c * 2^{-12} + d * 2^{-20}, if a = 255. + * + * (No other choices of a are allowed, since the magnitude of a TFM dimension + * must be less than 16.) We want to multiply this quantity by the integer + * z, which is known to be less than 2^{27}. Let \alpha = 16z. If z < + * 2^{23}, the individual multiplications b * z, c * z, d * z cannot + * overflow; otherwise we will divide z by 2, 4, 8, or 16, to obtain a + * multiplier less than 2^{23}, and we can compensate for this later. If z + * has thereby been replaced by z' = z/2^e, let \beta = 2^{4-e}; we shall + * compute + * + * \lfloor (b + c * 2^{-8} + d * 2^{-16})z' / \beta \rfloor + * + * if a = 0, or the same quantity minus \alpha if a = 255. This calculation + * must be done exactly, for the reasons stated above; the following program + * does the job in a system-independent way, assuming that arithmetic is + * exact on numbers less than 2^{31} in magnitude.'' + */ +#define ZLIM ((i32)1 << 23) /* z must be < zlim */ + +/* + * Scale the single TFM width t by z. + */ +i32 +ScaleOneWidth(t, z) + register i32 t, z; +{ + register i32 alpha, log2beta; + register int a0; + + /* First compute \alpha, \beta, and z': */ + alpha = 16 * z; + log2beta = 4; + while (z >= ZLIM) { + z >>= 1; + log2beta--; + } + + /* The four values 'a', 'b', 'c', and 'd' are fields within t: */ +#define a (UnSign8(t >> 24)) +#define b (UnSign8(t >> 16)) +#define c (UnSign8(t >> 8)) +#define d (UnSign8(t)) + if (t) { + a0 = a; + t = (((((d * z) >> 8) + c * z) >> 8) + b * z) >> log2beta; + if (a0) { + if (a0 != 255) + error(0, 0, "bad TFM width! [ScaleOneWidth]"); + t -= alpha; + } + } + return (t); +} + +/* + * Scale a set of glyphs [l..h) in font f according to f->f_dvimag + * (that is, set g_tfmwidth from g_rawtfmwidth). + */ +ScaleGlyphs(f, l, h) + register struct font *f; + int l, h; +{ + register int i, a0; + register i32 t, z, alpha, log2beta; + + z = f->f_dvimag; + alpha = 16 * z; + log2beta = 4; + while (z >= ZLIM) { + z >>= 1; + log2beta--; + } + + for (i = l; i < h; i++) { + if ((t = f->f_gly[i]->g_rawtfmwidth) != 0) { + a0 = a; + t = (((((d * z) >> 8) + c * z) >> 8) + b * z) >> + log2beta; + if (a0) { + if (a0 != 255) + error(0, 0, + "\"%s\", glyph %d: bad TFM width", + f->f_path, i); + t -= alpha; + } + } + f->f_gly[i]->g_tfmwidth = t; + } +} |