[cairo] Re: [Librsvg-devel] Porting librsvg to an Embedded
Platform
Bill Spitzak
spitzak at d2.com
Thu Oct 5 11:37:36 PDT 2006
Carl Worth wrote:
> * Use a much faster method for converting floating-point to
> fixed-point, (taking advantage of IEEE floating-point representation
> when possible). There are patches that have been proposed to do
> this, but none of them yet have the configure-time checks to ensure
> that the method can reliably be used. There is also some open
> discussion about which rounding mode we want, but I'm guessing it
> really won't matter down at the level of the fixed-point sub-pixel
> grid.
Attached is a fast_rint function that work with GCC 4.0 with full
optimizations, and with the Intel and Windows compilers. I also attached
what I believe are converters to 16.16 and 24.8, but these are not tested.
These work by adding a large enough constant that the interesting
portion of the number is shifted right to a fixed location in the low
half of the double. The actual rounding these functions do depends on
the current setting of the floating point processor. It matches, except
toward-zero will end up acting like floor (due to the large positive
number added).
It is possible to check for overflow by asserting that the "hi" field
has the right value after the addition. This value is a constant for
each of these, sorry I don't know what it is.
Since these conversions involve adding a large positive number, it would
be possible to merge this into the matrix multiplication by putting the
constant into the xy offsets, as though a translation is always being
done to this very large xy location.
// Attached code is released into the public domain by the author, Bill
// Spitzak. Code may be used for any purpose.
// Warning: we assume long is a 32 bit and double is 64 bit IEEE!
union Double_Long {
double v;
#if __BIG_ENDIAN__
long hi, low;
#else
long low, hi;
#endif
long long big;
};
/*! Fast version of (int)rint().
Works for -2147483648.5 .. 2147483647.49975574019
*/
inline long fast_rint(double val) {
Double_Long v; v.v = val + 68719476736.0*65536.0*1.5;
return v.low;
}
/*! Fast converter to 24.8 representation.
Works for -8388608.00195 to 8388607.99805
*/
inline long fast_24_8(double val) {
Double_Long v; v.v = val + (68719476736.0*256.0*1.5);
return v.low;
}
/*! Fast converter to 16.16 representation.
Works for -32768.0000076 to 32767.9999924
*/
inline long fast_16_16(double val) {
Double_Long v; v.v = val + (68719476736.0*1.5);
return v.low;
}
More information about the cairo
mailing list