📄 ftbbox.c
字号:
/***************************************************************************//* *//* ftbbox.c *//* *//* FreeType bbox computation (body). *//* *//* Copyright 1996-2000 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. */ /* */ /* It is separated from the rest of the engine for various technical */ /* reasons. It may well be integrated in `ftoutln' later. */ /* */ /*************************************************************************/#include <ftbbox.h>#include <ftimage.h>#include <ftobjs.h> typedef struct TBBox_Rec_ { FT_Vector last; FT_BBox bbox; } TBBox_Rec; /*************************************************************************/ /* */ /* <Function> */ /* BBox_Move_To */ /* */ /* <Description> */ /* This function is used as a `move_to' and `line_to' emitter during */ /* FT_Raster_Decompose(). It simply records the destination point in */ /* `user->last'. */ /* */ /* <Input> */ /* to :: A pointer to the destination vector. */ /* */ /* <InOut> */ /* user :: A pointer to the current walk context. */ /* */ /* <Return> */ /* Error code. 0 means success. */ /* */ static int BBox_Move_To( FT_Vector* to, TBBox_Rec* user ) { user->last = *to; return 0; }#define CHECK_X( p, bbox ) \ ( p->x < bbox.xMin || p->x > bbox.xMax )#define CHECK_Y( p, bbox ) \ ( p->y < bbox.yMin || p->y > bbox.yMax ) /*************************************************************************/ /* */ /* <Function> */ /* BBox_Conic_Check */ /* */ /* <Description> */ /* Finds 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 ) { if( y1 == y3 ) { if ( y2 == y1 ) /* Flat arc */ { y3 = y1; goto Suite; } } else if ( y1 < y3 ) { if ( y2 >= y1 && y2 <= y3 ) /* Ascending arc */ goto Suite; } else { if ( y2 >= y3 && y2 <= y1 ) /* Descending arc */ { y2 = y1; y1 = y3; y3 = y2; goto Suite; } } y1 = y3 = FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 ); Suite: if ( y1 < *min ) *min = y1; if ( y3 > *max ) *max = y3; } /*************************************************************************/ /* */ /* <Function> */ /* BBox_Conic_To */ /* */ /* <Description> */ /* This function is used as a `conic_to' emitter during */ /* FT_Raster_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> */ /* Error code. 0 means success. */ /* */ /* <Note> */ /* In the case of a non-monotonous arc, we compute directly the */ /* extremum coordinates, as it is sufficiently fast. */ /* */ static int BBox_Conic_To( FT_Vector* control, FT_Vector* to, TBBox_Rec* user ) { if ( CHECK_X( control, user->bbox ) || CHECK_X( to, user->bbox ) ) BBox_Conic_Check( user->last.x, control->x, to->x, &user->bbox.xMin, &user->bbox.xMax ); if ( CHECK_Y( control, user->bbox ) || CHECK_Y( to, user->bbox ) ) BBox_Conic_Check( user->last.y, control->y, to->y, &user->bbox.yMin, &user->bbox.yMax ); return 0; } /*************************************************************************/ /* */ /* <Function> */ /* BBox_Cubic_Check */ /* */ /* <Description> */ /* Finds the extrema of a 1-dimensional cubic Bezier curve and */ /* updates a bounding range. This version uses splitting because we */ /* don't want to use square roots and extra accuracies. */ /* */ /* <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 void BBox_Cubic_Check( FT_Pos p1, FT_Pos p2, FT_Pos p3, FT_Pos p4, FT_Pos* min, FT_Pos* max ) { FT_Pos stack[33], *arc; arc = stack; arc[0] = p1; arc[1] = p2; arc[2] = p3; arc[3] = p4; do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -