[base] Finish experimental (disabled) BBox_Cubic_Check implementation.
* src/base/ftbbox.c (BBox_Cubic_Check): Scale arguments to improve accuracy and avoid overflows.
This commit is contained in:
parent
61a65510dc
commit
1a9c3d14fb
10
ChangeLog
10
ChangeLog
|
@ -1,9 +1,17 @@
|
|||
2013-08-15 Alexei Podtelezhnikov <apodtele@gmail.com>
|
||||
|
||||
[base] Finish experimental (disabled) BBox_Cubic_Check implementation.
|
||||
|
||||
* src/base/ftbbox.c (BBox_Cubic_Check): Scale arguments to improve
|
||||
accuracy and avoid overflows.
|
||||
|
||||
2013-08-13 Alexei Podtelezhnikov <apodtele@gmail.com>
|
||||
|
||||
[base] Refactor experimental (disabled) BBox_Cubic_Check.
|
||||
|
||||
* src/base/ftbbox.c (BBox_Cubic_Check): Implement the minimum search
|
||||
as the mirror image of the maximum search.
|
||||
as the mirror image of the maximum search implemented here...
|
||||
(update_max): New function.
|
||||
|
||||
2013-08-06 John Tytgat <John.Tytgat@esko.com>
|
||||
|
||||
|
|
|
@ -275,10 +275,62 @@
|
|||
FT_Pos* min,
|
||||
FT_Pos* max )
|
||||
{
|
||||
*max = update_max( p1, p2, p3, p4, *max );
|
||||
FT_Pos nmin, nmax;
|
||||
FT_Int shift;
|
||||
|
||||
/* This implementation relies on iterative bisection of the segment. */
|
||||
/* The fixed-point arithmentic of bisection is inherently stable but */
|
||||
/* may loose accuracy in the two lowest bits. To compensate, we */
|
||||
/* upscale the segment if there is room. Large values may need to be */
|
||||
/* downscaled to avoid overflows during bisection bisection. This */
|
||||
/* function is only called when a control off-point is outside the */
|
||||
/* the bbox and, thus, has the top absolute value among arguments. */
|
||||
|
||||
shift = 27 - FT_MSB( FT_ABS( p2 ) | FT_ABS( p3 ) );
|
||||
|
||||
if ( shift > 0 )
|
||||
{
|
||||
/* upscaling too much just wastes time */
|
||||
if ( shift > 2 )
|
||||
shift = 2;
|
||||
|
||||
p1 <<= shift;
|
||||
p2 <<= shift;
|
||||
p3 <<= shift;
|
||||
p4 <<= shift;
|
||||
nmin = *min << shift;
|
||||
nmax = *max << shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
p1 >>= -shift;
|
||||
p2 >>= -shift;
|
||||
p3 >>= -shift;
|
||||
p4 >>= -shift;
|
||||
nmin = *min >> -shift;
|
||||
nmax = *max >> -shift;
|
||||
}
|
||||
|
||||
nmax = update_max( p1, p2, p3, p4, nmax );
|
||||
|
||||
/* now flip the signs to update the minimum */
|
||||
*min = -update_max( -p1, -p2, -p3, -p4, -*min );
|
||||
nmin = -update_max( -p1, -p2, -p3, -p4, -nmin );
|
||||
|
||||
if ( shift > 0 )
|
||||
{
|
||||
nmin >>= shift;
|
||||
nmax >>= shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
nmin <<= -shift;
|
||||
nmax <<= -shift;
|
||||
}
|
||||
|
||||
if ( nmin < *min )
|
||||
*min = nmin;
|
||||
if ( nmax > *max )
|
||||
*max = nmax;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -482,8 +534,9 @@
|
|||
FT_Vector* to,
|
||||
TBBox_Rec* user )
|
||||
{
|
||||
/* we don't need to check `to' since it is always an `on' point, thus */
|
||||
/* within the bbox */
|
||||
/* We don't need to check `to' since it is always an on-point, */
|
||||
/* thus within the bbox. Only segments with an off-point outside */
|
||||
/* the bbox can possibly reach new extreme values. */
|
||||
|
||||
if ( CHECK_X( control1, user->bbox ) ||
|
||||
CHECK_X( control2, user->bbox ) )
|
||||
|
|
Loading…
Reference in New Issue