/**************************************************************************** * * ftbbox.c * * FreeType bbox computation (body). * * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used * modified and distributed under the terms of the FreeType project * license, LICENSE.TXT. By continuing to use, modify, or distribute * this file you indicate that you have read the license and * understand and accept it fully. * */ /************************************************************************** * * This component has a _single_ role: to compute exact outline bounding * boxes. * */ #include <freetype/internal/ftdebug.h> #include <freetype/ftbbox.h> #include <freetype/ftimage.h> #include <freetype/ftoutln.h> #include <freetype/internal/ftcalc.h> #include <freetype/internal/ftobjs.h> TBBox_Rec; #define FT_UPDATE_BBOX( p, bbox ) … #define CHECK_X( p, bbox ) … #define CHECK_Y( p, bbox ) … /************************************************************************** * * @Function: * BBox_Move_To * * @Description: * This function is used as a `move_to' emitter during * FT_Outline_Decompose(). It simply records the destination point * in `user->last'. We also update bbox in case contour starts with * an implicit `on' point. * * @Input: * to :: * A pointer to the destination vector. * * @InOut: * user :: * A pointer to the current walk context. * * @Return: * Always 0. Needed for the interface only. */ FT_CALLBACK_DEF( int ) BBox_Move_To( const FT_Vector* to, void* user_ ) { … } /************************************************************************** * * @Function: * BBox_Line_To * * @Description: * This function is used as a `line_to' emitter during * FT_Outline_Decompose(). It simply records the destination point * in `user->last'; no further computations are necessary because * bbox already contains both explicit ends of the line segment. * * @Input: * to :: * A pointer to the destination vector. * * @InOut: * user :: * A pointer to the current walk context. * * @Return: * Always 0. Needed for the interface only. */ FT_CALLBACK_DEF( int ) BBox_Line_To( const FT_Vector* to, void* user_ ) { … } /************************************************************************** * * @Function: * BBox_Conic_Check * * @Description: * Find the extrema of a 1-dimensional conic Bezier curve and update * a bounding range. This version uses direct computation, as it * doesn't need square roots. * * @Input: * y1 :: * The start coordinate. * * y2 :: * The coordinate of the control point. * * y3 :: * The end coordinate. * * @InOut: * min :: * The address of the current minimum. * * max :: * The address of the current maximum. */ static void BBox_Conic_Check( FT_Pos y1, FT_Pos y2, FT_Pos y3, FT_Pos* min, FT_Pos* max ) { … } /************************************************************************** * * @Function: * BBox_Conic_To * * @Description: * This function is used as a `conic_to' emitter during * FT_Outline_Decompose(). It checks a conic Bezier curve with the * current bounding box, and computes its extrema if necessary to * update it. * * @Input: * control :: * A pointer to a control point. * * to :: * A pointer to the destination vector. * * @InOut: * user :: * The address of the current walk context. * * @Return: * Always 0. Needed for the interface only. * * @Note: * In the case of a non-monotonous arc, we compute directly the * extremum coordinates, as it is sufficiently fast. */ FT_CALLBACK_DEF( int ) BBox_Conic_To( const FT_Vector* control, const FT_Vector* to, void* user_ ) { … } /************************************************************************** * * @Function: * BBox_Cubic_Check * * @Description: * Find the extrema of a 1-dimensional cubic Bezier curve and * update a bounding range. This version uses iterative splitting * because it is faster than the exact solution with square roots. * * @Input: * p1 :: * The start coordinate. * * p2 :: * The coordinate of the first control point. * * p3 :: * The coordinate of the second control point. * * p4 :: * The end coordinate. * * @InOut: * min :: * The address of the current minimum. * * max :: * The address of the current maximum. */ static FT_Pos cubic_peak( FT_Pos q1, FT_Pos q2, FT_Pos q3, FT_Pos q4 ) { … } static void BBox_Cubic_Check( FT_Pos p1, FT_Pos p2, FT_Pos p3, FT_Pos p4, FT_Pos* min, FT_Pos* max ) { … } /************************************************************************** * * @Function: * BBox_Cubic_To * * @Description: * This function is used as a `cubic_to' emitter during * FT_Outline_Decompose(). It checks a cubic Bezier curve with the * current bounding box, and computes its extrema if necessary to * update it. * * @Input: * control1 :: * A pointer to the first control point. * * control2 :: * A pointer to the second control point. * * to :: * A pointer to the destination vector. * * @InOut: * user :: * The address of the current walk context. * * @Return: * Always 0. Needed for the interface only. * * @Note: * In the case of a non-monotonous arc, we don't compute directly * extremum coordinates, we subdivide instead. */ FT_CALLBACK_DEF( int ) BBox_Cubic_To( const FT_Vector* control1, const FT_Vector* control2, const FT_Vector* to, void* user_ ) { … } FT_DEFINE_OUTLINE_FUNCS( bbox_interface, (FT_Outline_MoveTo_Func) BBox_Move_To, /* move_to */ (FT_Outline_LineTo_Func) BBox_Line_To, /* line_to */ (FT_Outline_ConicTo_Func)BBox_Conic_To, /* conic_to */ (FT_Outline_CubicTo_Func)BBox_Cubic_To, /* cubic_to */ 0, /* shift */ 0 /* delta */ ) /* documentation is in ftbbox.h */ FT_EXPORT_DEF( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, FT_BBox *abbox ) { … } /* END */