|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 3279 (0xccf)
Types: TextFile
Names: »conv.h«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
└─⟦this⟧ »./DVIware/laser-setters/umd-dvi/h/conv.h«
/*
* Copyright (c) 1987 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-dependenent 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.
*/
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?) */
} Conversion;
/*
* 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
static double _half = 0.5;
static double _zero = 0.0;
static double _d;
#define ROUND(f) ((i32) (_d = (f), _d < _zero ? _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();