freetype-devel
[Top][All Lists]
Advanced

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

Re: [Devel] Integer issues with FreeType


From: David Turner
Subject: Re: [Devel] Integer issues with FreeType
Date: Sat, 21 Apr 2001 09:14:35 +0200

Hi Antoine,

Antoine Leca a écrit :
> 
> > The sizes defined by the ANSI C specification, which is:
> >
> >   FT_Short  == short  == 16-bits
> >   FT_Int    == int    == at least 16 bits, can be more (i.e. 24 bits, 32 
> > bits, etc..)
> >   FT_Long   == long   == at least 32 bits, can be more (i.e. 36 bits, 64 
> > bits, etc..)
> 
> To be exact:
>     FT_Short  == short  == at least 16 bits, can be more (i.e. 24 bits, 32 
> bits, 64
> bits, etc..)
>     FT_Int    == int    == at least as wide as FT_Short, can be more
>     FT_Long   == long   == at least as wide as FT_Int, AND at least 32 bits, 
> can be
> more
>
Thanks for the correction. Why I was convinced that a short was only 16-bits is
a mystery to me (it just probably shows my age, I'll reach 30 next September ;-)

> 
> > You should use the FT_IntXX and FT_UIntXX types only when you
> > absolutely need an integer of an exact size. This is generally
> > used when you're dealing with the structure of integers in
> > memory, or when you need to perform exact wrapping, like in
> > "((FT_UInt16)(x + 16))"..
> 
> I do believe this is true only for the unsigned ones,
> i.e. I believe we should avoid using the signed versions.
>
What do you mean exactly ?

  (x + 16) will be promoted to an int, so you'll need to
  cast it to a (FT_Int16) if you need to avoid compiler
  warnings in many cases..
 
> In other words, if one use FT_Int (which I believe is the correct thing to
> do for any "small" variable), the only point that should be checked vs. 16-bit
> issues, is whether any computations, *including* internal sub-expressions,
> cannot overflow a 15-bit value (of course, particular attention must
> be exercised after *any* use of the multiplication operator, because
> this is the principal culprit).
> The "fix" for this is two-sided:
> - one should use FT_Long for all internal variables that may exceed 15-bit;
> - one should suffix with L any constant (such as 64 often used in the TrueType
>   driver) that comes into action as operand of a * operator, when then
>   other operand is, for any reason, typed as FT_Int (or FT_Short), and the
>   (intermediate) result may overflow; equivalently, (FT_Long) casts may
>   be used.
> The result of this fix is a increased use of long all along the code,
> which, particularly on a platform where (64-bit) long are wider than
> (32-bit) int/short; and this leads to bigger size along with less
> performances. The only gain is scalability back to 16-bit boxes.
>
There is an alternative way to "fix" this without affecting too much 
performance.

  - first, define a given integer type (let's call it FT_Fast32 for now)
    that is guaranteed to be at least 32-bit while still being fast to
    use. This would be defined as

          #if FT_SIZEOF_INT == 2
             typedef long           FT_Fast32;
          #elif FT_SIZEOF_INT == 4
             typedef int   FT_Fast32;
          #else
          #  error  Oh my, what's this weird platform of yours ??!
          #endif

          typedef unsigned FT_Fast32    FT_UFast32;

    notice that this isn't the same thing than FT_Int32. I think we could
    replace nearly all uses of FT_Long (except for storage issues) with
    FT_Fast32 in the FreeType source code..


  - second, define some macros to perform the usual FreeType multiplications
    so you get something like:

     #if FT_SIZEOF_INT == 2
     #  define  FT_CONST32(x)      x##L
     #elif FT_SIZEOF_INT == 4
     #  define  FT_CONST32(x)      x
     #else
     #  error  Sorry, but Klingon processors aren't supported yet..
     #endif

     #define  FT_UPSCALE(x)        ((x) * FT_CONST32(64))
     #define  FT_INT_TO_FIXED(x)   ((x) * 0x10000L)
     
    this replaces the "x*64" and "x << 16" (the latter shouldn't be used
    anymore, unless with explicit FT_Int32 variables..

> Now, we had a test some weeks ago, and it showed that nobody really did use
> Freetype 2 on a 16-bit box, ever (alternatively, one may believe that there
> are not any 16-bit bug; I won't believe that).
>
I won't believe it either :-)
 
> And the other hand, the way it was done (by Werner) in Freetype 1, when
> compiling on a big platform with looong (i.e., wider than int) long's, one
> can customize FT_Long to stay within the 32-bit range. Yes, this gains
> performance and size. BUT this impeedes portability, and this is desastrous
> for maintenance, since the obvious meaning is not the real one. I do not
> believe there is any gain doing that.
> As a result, I do not see any reason to keep FT_Int, FT_Long, etc., and
> we may get back to the basic types, int, long, etc. Or do I miss something?
> David?
>
FT_Int and FT_Long exist for convenience. Basically:

    - because "unsigned int" and "unsigned long" are pretty long
      to write, they make the specific formatting of the FreeType
      source code painful (mainly because we align so much "columns")
      so FT_UInt and FT_ULong were introduced.

    - "int" and "long" are syntax-hilighted by most editors, while
      "FT_UInt" and "FT_ULong" aren't. This makes for sometimes
      confusing code to read, so "FT_Int" and "FT_Long" were
      introduced to have a cleaner code..

Yes, it's really a presentation issue, and I never expected to use
them for "32-bit ints", that would probably too confusing for most
developers that do not routinely hack the code..

Regards,

- David



reply via email to

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