freetype
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft] FT_Outline_Render makes different bitmaps in 32-bit and 64-bit


From: Tom Bishop, Wenlin Institute
Subject: Re: [ft] FT_Outline_Render makes different bitmaps in 32-bit and 64-bit programs?
Date: Tue, 26 Oct 2010 11:35:57 -0700

On Oct 26, 2010, at 7:49 AM, Werner LEMBERG wrote:

>> It seems that this bug appears since a change between 2.3.9 and
>> 2.3.10: [...]
> 
> Thanks in advance for investigating the problem.  Since I don't have
> access to a 64bit system, I unfortunately can't help much.

It seems that the bug occurs in 32-bit programs, and not in 64-bit programs, so 
in principle it could be debugged with a 32-bit system. (Or is it possible the 
bug only occurs in 32-bit programs running on 64-bit systems? I don't currently 
have a 32-bit machine to test on.)

Thanks to mpsuzuki's last message, I found two solutions, either one of which 
solves the problem at least as it occurs in the test program.

The first is to change ftOutline.flags from FT_OUTLINE_HIGH_PRECISION to 
FT_OUTLINE_NONE.

The second is to modify Set_High_Precision() in ftraster.c to use 10, 128, 24 
instead of 12, 256, 50.

I haven't tested whether either solution leads to any subtle loss of quality, 
but they do solve the big problem.

Here are a couple thoughts. fttypes.h has typedefs like the following:

typedef signed long  FT_F26Dot6;

This may be 64 bits even though the name FT_F26Dot6 itself suggests it doesn't 
need to be more than 32 bits. Maybe there is nothing in Freetype that really 
needs to be 64 bits. It could be worthwhile to have the option of using modern 
types such as int32_t where supported, like this:

#if FREETYPE_USE_STDINT
#include <stdint.h>
typedef int32_t FT_F26Dot6;
#else
typedef signed long FT_F26Dot6;
#endif

That might reduce the amount of memory required on some 64-bit systems, as well 
as ensure more consistency of behavior between 32- and 64-bit systems.

Here's something surprising about C that I learned recently:

        int a = -1;
        unsigned int b = 0;
        if (a > b) printf("Surprisingly, -1 > 0\n");

        long c = -1;
        unsigned short d = 0;
        if (c < d) printf("Nevertheless, -1 < 0\n");

The moral is that bugs are likely when mixing integers that differ in size or 
sign. With that in mind, macros like the following in ftraster.c seem 
suspicious:

#define CEILING( x )  ( ( (x) + ras.precision - 1 ) & -ras.precision )
#define TRUNC( x )    ( (signed long)(x) >> ras.precision_bits )
#define IS_BOTTOM_OVERSHOOT( x )  ( CEILING( x ) - x >= ras.precision_half )
...

There's a comment that "These operations are only valid on 2's complement 
processors", but even then can we be sure they're valid when used with mixtures 
of signed and unsigned shorts, ints, and longs? Given that even the smallest 
machines nowadays are at least 32-bit, maybe the code would be more stable, 
without significant loss of efficiency, if the integers were all 32-bit. That 
is, both 16-bit shorts and 64-bit longs could be avoided. (I realize that's 
more easily said than done!)

Yours,

Tom

文林 Wenlin Institute, Inc.        Software for Learning Chinese
E-mail: address@hidden     Web: http://www.wenlin.com
Telephone: 1-877-4-WENLIN (1-877-493-6546)
☯








reply via email to

[Prev in Thread] Current Thread [Next in Thread]