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: Werner LEMBERG
Subject: Re: [ft] FT_Outline_Render makes different bitmaps in 32-bit and 64-bit programs?
Date: Thu, 28 Oct 2010 08:53:20 +0200 (CEST)

> The bug appears to be here in ftraster.c: [...]
>
> #define FMulDiv FT_MulDiv
>
> (same as SMulDiv) solves the bug.

Thanks a lot for the detailed analysis!  I've already replaced some
FMulDiv calls with SMulDiv a longer time ago, IIRC, but one case has
escaped me.  Fixed in git.

> For the test program, there are many reports where fast and slow
> differ only slightly:
>
> Problem in FMulDiv (162, 163)
> Problem in FMulDiv (461, 462)
> Problem in FMulDiv (49, 50)

This is expected, since FMulDiv doesn't round.

> Maybe the solution could be optimized for speed by determining which
> calls to FMulDiv() are failing badly, and changing them to
> SMulDiv(), while retaining the old FMulDiv() where appropriate; but
> how one can assume such a limitation on the size of path
> coordinates? And is FT_MulDiv() really slow enough to make a big
> difference?

Let's wait for user reports :-)  I've just fixed the offending call,
and I get fine output now.

> (1) ras.precision_mask is never used. The macros like FLOOR() use
> "-ras.precision"; maybe they were supposed to use
> ras.precision_mask.

I've removed it.  Fixed in git.

> (2) ULong is never used.

Removed also.  Fixed in git.

> (3) Changing Int, Short, Long, and *PLong all to int32_t, and
> changing UInt, UShort, and *PUShort all to uint32_t seems to make no
> difference to the behavior when running as 32-bit, but when running
> as 64-bit, it crashed with EXC_BAD_ACCESS at this line in
> Draw_Sweep():
>
>    P->countL = (UShort)( P->start - min_Y );
>
> -- because P wasn't a valid pointer; P->link had become corrupted.
> This line in Finalize_Profile_Table() is suspicious:
>
>    p->link = (PProfile)( p->offset + p->height );
>
> Note p->offset is type PLong, so the assumption seems to be made
> that sizeof(PProfile) == sizeof(Long), i.e., sizeof(struct TProfile_
> *) == sizeof(Long), or in general, sizeof(void *) == sizeof(Long).
> Here's one example where Freetype does need 64-bit items, to store
> pointers when running in a 64-bit program; but it seems problematic
> to assume a pointer is the same size as any type of integer.  If
> p->offset is used for storage of PProfile, shouldn't its type be
> PProfile rather than PLong?

I think you are right.  Can you provide a patch?  I don't have a
64bit system for testing.  Maybe Toshiya-san could check it then.


    Werner



reply via email to

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