44#define FT_UPDATE_BBOX( p, bbox ) \
46 if ( p->x < bbox.xMin ) \
48 if ( p->x > bbox.xMax ) \
50 if ( p->y < bbox.yMin ) \
52 if ( p->y > bbox.yMax ) \
56#define CHECK_X( p, bbox ) \
57 ( p->x < bbox.xMin || p->x > bbox.xMax )
59#define CHECK_Y( p, bbox ) \
60 ( p->y < bbox.yMin || p->y > bbox.yMax )
85 FT_CALLBACK_DEF(
int )
86 BBox_Move_To(
const FT_Vector* to,
89 TBBox_Rec* user = (TBBox_Rec*)user_;
92 FT_UPDATE_BBOX( to, user->bbox );
122 FT_CALLBACK_DEF(
int )
123 BBox_Line_To(
const FT_Vector* to,
126 TBBox_Rec* user = (TBBox_Rec*)user_;
163 BBox_Conic_Check( FT_Pos y1,
176 y2 += FT_MulDiv( y1, y3, y1 + y3 );
214 FT_CALLBACK_DEF(
int )
215 BBox_Conic_To(
const FT_Vector* control,
219 TBBox_Rec* user = (TBBox_Rec*)user_;
223 FT_UPDATE_BBOX( to, user->bbox );
225 if ( CHECK_X( control, user->bbox ) )
226 BBox_Conic_Check( user->last.x,
232 if ( CHECK_Y( control, user->bbox ) )
233 BBox_Conic_Check( user->last.y,
276 cubic_peak( FT_Pos q1,
294 shift = 27 - FT_MSB( (FT_UInt32)( FT_ABS( q1 ) |
320 while ( q2 > 0 || q3 > 0 )
323 if ( q1 + q2 > q3 + q4 )
330 q4 = ( q4 + q3 ) >> 3;
341 q1 = ( q1 + q2 ) >> 3;
347 if ( q1 == q2 && q1 >= q3 )
352 if ( q3 == q4 && q2 <= q4 )
369 BBox_Cubic_Check( FT_Pos p1,
381 if ( p2 > *max || p3 > *max )
382 *max += cubic_peak( p1 - *max, p2 - *max, p3 - *max, p4 - *max );
385 if ( p2 < *min || p3 < *min )
386 *min -= cubic_peak( *min - p1, *min - p2, *min - p3, *min - p4 );
422 FT_CALLBACK_DEF(
int )
423 BBox_Cubic_To(
const FT_Vector* control1,
424 const FT_Vector* control2,
428 TBBox_Rec* user = (TBBox_Rec*)user_;
435 if ( CHECK_X( control1, user->bbox ) ||
436 CHECK_X( control2, user->bbox ) )
437 BBox_Cubic_Check( user->last.x,
444 if ( CHECK_Y( control1, user->bbox ) ||
445 CHECK_Y( control2, user->bbox ) )
446 BBox_Cubic_Check( user->last.y,
459 FT_DEFINE_OUTLINE_FUNCS(
462 (FT_Outline_MoveTo_Func) BBox_Move_To,
463 (FT_Outline_LineTo_Func) BBox_Line_To,
464 (FT_Outline_ConicTo_Func)BBox_Conic_To,
465 (FT_Outline_CubicTo_Func)BBox_Cubic_To,
473 FT_EXPORT_DEF( FT_Error )
474 FT_Outline_Get_BBox( FT_Outline* outline,
477 FT_BBox cbox = { 0x7FFFFFFFL, 0x7FFFFFFFL,
478 -0x7FFFFFFFL, -0x7FFFFFFFL };
479 FT_BBox bbox = { 0x7FFFFFFFL, 0x7FFFFFFFL,
480 -0x7FFFFFFFL, -0x7FFFFFFFL };
486 return FT_THROW( Invalid_Argument );
489 return FT_THROW( Invalid_Outline );
492 if ( outline->n_points == 0 || outline->n_contours == 0 )
494 abbox->xMin = abbox->xMax = 0;
495 abbox->yMin = abbox->yMax = 0;
504 vec = outline->points;
506 for ( n = 0; n < outline->n_points; n++ )
508 FT_UPDATE_BBOX( vec, cbox );
510 if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON )
511 FT_UPDATE_BBOX( vec, bbox );
517 if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax ||
518 cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax )
529 error = FT_Outline_Decompose( outline, &bbox_interface, &user );