OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ftbbox.c */ | 3 /* ftbbox.c */ |
4 /* */ | 4 /* */ |
5 /* FreeType bbox computation (body). */ | 5 /* FreeType bbox computation (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 1996-2002, 2004, 2006, 2010, 2013, 2014 by */ | 7 /* Copyright 1996-2015 by */ |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
9 /* */ | 9 /* */ |
10 /* This file is part of the FreeType project, and may only be used */ | 10 /* This file is part of the FreeType project, and may only be used */ |
11 /* modified and distributed under the terms of the FreeType project */ | 11 /* modified and distributed under the terms of the FreeType project */ |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
15 /* */ | 15 /* */ |
16 /***************************************************************************/ | 16 /***************************************************************************/ |
17 | 17 |
(...skipping 17 matching lines...) Expand all Loading... |
35 | 35 |
36 | 36 |
37 typedef struct TBBox_Rec_ | 37 typedef struct TBBox_Rec_ |
38 { | 38 { |
39 FT_Vector last; | 39 FT_Vector last; |
40 FT_BBox bbox; | 40 FT_BBox bbox; |
41 | 41 |
42 } TBBox_Rec; | 42 } TBBox_Rec; |
43 | 43 |
44 | 44 |
45 #define FT_UPDATE_BBOX(p, bbox) \ | 45 #define FT_UPDATE_BBOX( p, bbox ) \ |
46 FT_BEGIN_STMNT \ | 46 FT_BEGIN_STMNT \ |
47 if ( p->x < bbox.xMin ) \ | 47 if ( p->x < bbox.xMin ) \ |
48 bbox.xMin = p->x; \ | 48 bbox.xMin = p->x; \ |
49 if ( p->x > bbox.xMax ) \ | 49 if ( p->x > bbox.xMax ) \ |
50 bbox.xMax = p->x; \ | 50 bbox.xMax = p->x; \ |
51 if ( p->y < bbox.yMin ) \ | 51 if ( p->y < bbox.yMin ) \ |
52 bbox.yMin = p->y; \ | 52 bbox.yMin = p->y; \ |
53 if ( p->y > bbox.yMax ) \ | 53 if ( p->y > bbox.yMax ) \ |
54 bbox.yMax = p->y; \ | 54 bbox.yMax = p->y; \ |
55 FT_END_STMNT | 55 FT_END_STMNT |
56 | 56 |
57 #define CHECK_X( p, bbox ) \ | 57 #define CHECK_X( p, bbox ) \ |
58 ( p->x < bbox.xMin || p->x > bbox.xMax ) | 58 ( p->x < bbox.xMin || p->x > bbox.xMax ) |
59 | 59 |
60 #define CHECK_Y( p, bbox ) \ | 60 #define CHECK_Y( p, bbox ) \ |
61 ( p->y < bbox.yMin || p->y > bbox.yMax ) | 61 ( p->y < bbox.yMin || p->y > bbox.yMax ) |
62 | 62 |
63 | 63 |
64 /*************************************************************************/ | 64 /*************************************************************************/ |
65 /* */ | 65 /* */ |
66 /* <Function> */ | 66 /* <Function> */ |
67 /* BBox_Move_To */ | 67 /* BBox_Move_To */ |
68 /* */ | 68 /* */ |
69 /* <Description> */ | 69 /* <Description> */ |
70 /* This function is used as a `move_to' emitter during */ | 70 /* This function is used as a `move_to' emitter during */ |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 /* */ | 248 /* */ |
249 static FT_Pos | 249 static FT_Pos |
250 cubic_peak( FT_Pos q1, | 250 cubic_peak( FT_Pos q1, |
251 FT_Pos q2, | 251 FT_Pos q2, |
252 FT_Pos q3, | 252 FT_Pos q3, |
253 FT_Pos q4 ) | 253 FT_Pos q4 ) |
254 { | 254 { |
255 FT_Pos peak = 0; | 255 FT_Pos peak = 0; |
256 FT_Int shift; | 256 FT_Int shift; |
257 | 257 |
| 258 |
258 /* This function finds a peak of a cubic segment if it is above 0 */ | 259 /* This function finds a peak of a cubic segment if it is above 0 */ |
259 /* using iterative bisection of the segment, or returns 0. */ | 260 /* using iterative bisection of the segment, or returns 0. */ |
260 /* The fixed-point arithmetic of bisection is inherently stable */ | 261 /* The fixed-point arithmetic of bisection is inherently stable */ |
261 /* but may loose accuracy in the two lowest bits. To compensate, */ | 262 /* but may loose accuracy in the two lowest bits. To compensate, */ |
262 /* we upscale the segment if there is room. Large values may need */ | 263 /* we upscale the segment if there is room. Large values may need */ |
263 /* to be downscaled to avoid overflows during bisection. */ | 264 /* to be downscaled to avoid overflows during bisection. */ |
264 /* It is called with either q2 or q3 positive, which is necessary */ | 265 /* It is called with either q2 or q3 positive, which is necessary */ |
265 /* for the peak to exist and avoids undefined FT_MSB. */ | 266 /* for the peak to exist and avoids undefined FT_MSB. */ |
266 | 267 |
267 shift = 27 - | 268 shift = 27 - FT_MSB( (FT_UInt32)( FT_ABS( q1 ) | |
268 FT_MSB( FT_ABS( q1 ) | FT_ABS( q2 ) | FT_ABS( q3 ) | FT_ABS( q4 ) ); | 269 FT_ABS( q2 ) | |
| 270 FT_ABS( q3 ) | |
| 271 FT_ABS( q4 ) ) ); |
269 | 272 |
270 if ( shift > 0 ) | 273 if ( shift > 0 ) |
271 { | 274 { |
272 /* upscaling too much just wastes time */ | 275 /* upscaling too much just wastes time */ |
273 if ( shift > 2 ) | 276 if ( shift > 2 ) |
274 shift = 2; | 277 shift = 2; |
275 | 278 |
276 q1 <<= shift; | 279 q1 <<= shift; |
277 q2 <<= shift; | 280 q2 <<= shift; |
278 q3 <<= shift; | 281 q3 <<= shift; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 control2->y, | 415 control2->y, |
413 to->y, | 416 to->y, |
414 &user->bbox.yMin, | 417 &user->bbox.yMin, |
415 &user->bbox.yMax ); | 418 &user->bbox.yMax ); |
416 | 419 |
417 user->last = *to; | 420 user->last = *to; |
418 | 421 |
419 return 0; | 422 return 0; |
420 } | 423 } |
421 | 424 |
422 FT_DEFINE_OUTLINE_FUNCS(bbox_interface, | 425 |
| 426 FT_DEFINE_OUTLINE_FUNCS(bbox_interface, |
423 (FT_Outline_MoveTo_Func) BBox_Move_To, | 427 (FT_Outline_MoveTo_Func) BBox_Move_To, |
424 (FT_Outline_LineTo_Func) BBox_Line_To, | 428 (FT_Outline_LineTo_Func) BBox_Line_To, |
425 (FT_Outline_ConicTo_Func)BBox_Conic_To, | 429 (FT_Outline_ConicTo_Func)BBox_Conic_To, |
426 (FT_Outline_CubicTo_Func)BBox_Cubic_To, | 430 (FT_Outline_CubicTo_Func)BBox_Cubic_To, |
427 0, 0 | 431 0, 0 |
428 ) | 432 ) |
429 | 433 |
| 434 |
430 /* documentation is in ftbbox.h */ | 435 /* documentation is in ftbbox.h */ |
431 | 436 |
432 FT_EXPORT_DEF( FT_Error ) | 437 FT_EXPORT_DEF( FT_Error ) |
433 FT_Outline_Get_BBox( FT_Outline* outline, | 438 FT_Outline_Get_BBox( FT_Outline* outline, |
434 FT_BBox *abbox ) | 439 FT_BBox *abbox ) |
435 { | 440 { |
436 FT_BBox cbox = { 0x7FFFFFFF, 0x7FFFFFFF, -0x7FFFFFFF, -0x7FFFFFFF }; | 441 FT_BBox cbox = { 0x7FFFFFFFL, 0x7FFFFFFFL, |
437 FT_BBox bbox = { 0x7FFFFFFF, 0x7FFFFFFF, -0x7FFFFFFF, -0x7FFFFFFF }; | 442 -0x7FFFFFFFL, -0x7FFFFFFFL }; |
| 443 FT_BBox bbox = { 0x7FFFFFFFL, 0x7FFFFFFFL, |
| 444 -0x7FFFFFFFL, -0x7FFFFFFFL }; |
438 FT_Vector* vec; | 445 FT_Vector* vec; |
439 FT_UShort n; | 446 FT_UShort n; |
440 | 447 |
441 | 448 |
442 if ( !abbox ) | 449 if ( !abbox ) |
443 return FT_THROW( Invalid_Argument ); | 450 return FT_THROW( Invalid_Argument ); |
444 | 451 |
445 if ( !outline ) | 452 if ( !outline ) |
446 return FT_THROW( Invalid_Outline ); | 453 return FT_THROW( Invalid_Outline ); |
447 | 454 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 *abbox = user.bbox; | 500 *abbox = user.bbox; |
494 } | 501 } |
495 else | 502 else |
496 *abbox = bbox; | 503 *abbox = bbox; |
497 | 504 |
498 return FT_Err_Ok; | 505 return FT_Err_Ok; |
499 } | 506 } |
500 | 507 |
501 | 508 |
502 /* END */ | 509 /* END */ |
OLD | NEW |