diff options
Diffstat (limited to 'Build/source/texk/seetexk/conv.h')
-rw-r--r-- | Build/source/texk/seetexk/conv.h | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/Build/source/texk/seetexk/conv.h b/Build/source/texk/seetexk/conv.h new file mode 100644 index 00000000000..3350ff5a909 --- /dev/null +++ b/Build/source/texk/seetexk/conv.h @@ -0,0 +1,89 @@ +/* + * 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. + */ + +/* + * Conversions. Conversion factors convert between values in scaled + * points and values in device-dependent units. The results of all + * conversions are rounded to the nearest integral value, of type (i32). + */ + +/* + * This is now done using `double' values, but may be changed to + * fixed-point or some other `fast' method, as long as the results + * are consistent and reasonably accurate. The structure `conversion' + * holds the conversion-method-dependent quantities; the macros + * fromSP and toSP apply the conversion to a value. (Note that + * fromSP and toSP need not be macros, but should be fast.) + * + * SetConversion sets the (single, global) conversion factor. + * If a driver needs special conversions, there is another routine, + * CSetConversion that sets a specific conversion, and cfromSP and + * ctoSP to apply these. + * + * IS USING DOTS PER INCH SUFFICIENT? (Pixels per point might be better.) + * + * Note that it is necessary to set the global conversion factor before + * using any fonts. + */ +typedef struct conversion { + double c_fromsp; /* multiplier to convert from scaled points */ + double c_tosp; /* multiplier to convert to scaled points: + could divide by c_fromsp, but this should + be faster and more accurate */ + double c_mag; /* the magnification this conversion + represents; mainly for GetFont() */ + double c_dpi; /* dpi (should be pixels per point?) */ +} Conv; + +extern Conv Conversion; /* the global conversion factor */ + +/* + * In order to do this, we need to round properly. The compilers I + * have tend to generate very poor code for this. The following is + * intended to help them out. Smarter compilers can do better, but + * if they are smart enough, they will realise that the variables + * here are not used anywhere else, and discard them. (For a compiler + * to do this given separate compliation, `static' is a must.) + */ +#ifdef lint /* or a smart compiler */ + +#define ROUND(f) ((i32) ((f) < 0.0 ? (f) - 0.5 : (f) + 0.5)) +#define CEIL(f) ((double) (i32) (f) < (f) ? (i32) (f) + 1 : (i32) (f)) + +#else /* lint */ + +static double _half = 0.5; +static double _d; +#define ROUND(f) ((i32) (_d = (f), _d < 0.0 ? _d - _half : _d + _half)) + +#ifdef NEGATIVE_FLOAT_ROUNDS_TO_NEGATIVE_INFINITY +#define CEIL(f) (-(i32) -(f)) +#else /* we will assume that floating to integer truncates */ +static i32 _i; +#define CEIL(f) (_i = _d = (f), _i < _d ? _i + 1 : _i) +#endif /* round towards negative infinity */ + +#endif /* lint */ + +#define SetConversion(dpi, usermag, num, denom, dvimag) \ + CSetConversion(&Conversion, dpi, usermag, num, denom, dvimag) + +#define cfromSP(c, v) ROUND((c)->c_fromsp * (v)) +#define ctoSP(c, v) ROUND((c)->c_tosp * (v)) + +#define fromSP(v) cfromSP(&Conversion, v) +#define toSP(v) ctoSP(&Conversion, v) + +/* + * Conversions for rules are a bit different: we must round up, rather + * than off. ConvRule applies the global conversion value for a rule + * value (height or width); CConvRule applies a specific conversion. + */ +#define CConvRule(c, v) CEIL((c)->c_fromsp * (v)) +#define ConvRule(v) CConvRule(&Conversion, v) + +void CSetConversion(); |