| 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-2001, 2002, 2004, 2006, 2010 by                         */ | 7 /*  Copyright 1996-2002, 2004, 2006, 2010, 2013 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 | 
| 18 | 18 | 
| 19   /*************************************************************************/ | 19   /*************************************************************************/ | 
| 20   /*                                                                       */ | 20   /*                                                                       */ | 
| 21   /* This component has a _single_ role: to compute exact outline bounding */ | 21   /* This component has a _single_ role: to compute exact outline bounding */ | 
| 22   /* boxes.                                                                */ | 22   /* boxes.                                                                */ | 
| 23   /*                                                                       */ | 23   /*                                                                       */ | 
| 24   /*************************************************************************/ | 24   /*************************************************************************/ | 
| 25 | 25 | 
| 26 | 26 | 
| 27 #include <ft2build.h> | 27 #include <ft2build.h> | 
|  | 28 #include FT_INTERNAL_DEBUG_H | 
|  | 29 | 
| 28 #include FT_BBOX_H | 30 #include FT_BBOX_H | 
| 29 #include FT_IMAGE_H | 31 #include FT_IMAGE_H | 
| 30 #include FT_OUTLINE_H | 32 #include FT_OUTLINE_H | 
| 31 #include FT_INTERNAL_CALC_H | 33 #include FT_INTERNAL_CALC_H | 
| 32 #include FT_INTERNAL_OBJECTS_H | 34 #include FT_INTERNAL_OBJECTS_H | 
| 33 | 35 | 
| 34 | 36 | 
| 35   typedef struct  TBBox_Rec_ | 37   typedef struct  TBBox_Rec_ | 
| 36   { | 38   { | 
| 37     FT_Vector  last; | 39     FT_Vector  last; | 
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 215 #if 0 | 217 #if 0 | 
| 216 | 218 | 
| 217   static void | 219   static void | 
| 218   BBox_Cubic_Check( FT_Pos   p1, | 220   BBox_Cubic_Check( FT_Pos   p1, | 
| 219                     FT_Pos   p2, | 221                     FT_Pos   p2, | 
| 220                     FT_Pos   p3, | 222                     FT_Pos   p3, | 
| 221                     FT_Pos   p4, | 223                     FT_Pos   p4, | 
| 222                     FT_Pos*  min, | 224                     FT_Pos*  min, | 
| 223                     FT_Pos*  max ) | 225                     FT_Pos*  max ) | 
| 224   { | 226   { | 
| 225     FT_Pos  stack[32*3 + 1], *arc; | 227     FT_Pos  q1, q2, q3, q4; | 
| 226 | 228 | 
| 227 | 229 | 
| 228     arc = stack; | 230     q1 = p1; | 
|  | 231     q2 = p2; | 
|  | 232     q3 = p3; | 
|  | 233     q4 = p4; | 
| 229 | 234 | 
| 230     arc[0] = p1; | 235     /* for a conic segment to possibly reach new maximum     */ | 
| 231     arc[1] = p2; | 236     /* one of its off-points must be above the current value */ | 
| 232     arc[2] = p3; | 237     while ( q2 > *max || q3 > *max ) | 
| 233     arc[3] = p4; |  | 
| 234 |  | 
| 235     do |  | 
| 236     { | 238     { | 
| 237       FT_Pos  y1 = arc[0]; | 239       /* determine which half contains the maximum and split */ | 
| 238       FT_Pos  y2 = arc[1]; | 240       if ( q1 + q2 > q3 + q4 ) /* first half */ | 
| 239       FT_Pos  y3 = arc[2]; |  | 
| 240       FT_Pos  y4 = arc[3]; |  | 
| 241 |  | 
| 242 |  | 
| 243       if ( y1 == y4 ) |  | 
| 244       { | 241       { | 
| 245         if ( y1 == y2 && y1 == y3 )                         /* flat */ | 242         q4 = q4 + q3; | 
| 246           goto Test; | 243         q3 = q3 + q2; | 
|  | 244         q2 = q2 + q1; | 
|  | 245         q4 = q4 + q3; | 
|  | 246         q3 = q3 + q2; | 
|  | 247         q4 = ( q4 + q3 ) / 8; | 
|  | 248         q3 = q3 / 4; | 
|  | 249         q2 = q2 / 2; | 
| 247       } | 250       } | 
| 248       else if ( y1 < y4 ) | 251       else                     /* second half */ | 
| 249       { | 252       { | 
| 250         if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* ascending */ | 253         q1 = q1 + q2; | 
| 251           goto Test; | 254         q2 = q2 + q3; | 
| 252       } | 255         q3 = q3 + q4; | 
| 253       else | 256         q1 = q1 + q2; | 
| 254       { | 257         q2 = q2 + q3; | 
| 255         if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* descending */ | 258         q1 = ( q1 + q2 ) / 8; | 
| 256         { | 259         q2 = q2 / 4; | 
| 257           y2 = y1; | 260         q3 = q3 / 2; | 
| 258           y1 = y4; |  | 
| 259           y4 = y2; |  | 
| 260           goto Test; |  | 
| 261         } |  | 
| 262       } | 261       } | 
| 263 | 262 | 
| 264       /* unknown direction -- split the arc in two */ | 263       /* check if either end reached the maximum */ | 
| 265       arc[6] = y4; | 264       if ( q1 == q2 && q1 >= q3 ) | 
| 266       arc[1] = y1 = ( y1 + y2 ) / 2; | 265       { | 
| 267       arc[5] = y4 = ( y4 + y3 ) / 2; | 266         *max = q1; | 
| 268       y2 = ( y2 + y3 ) / 2; | 267         break; | 
| 269       arc[2] = y1 = ( y1 + y2 ) / 2; | 268       } | 
| 270       arc[4] = y4 = ( y4 + y2 ) / 2; | 269       if ( q3 == q4 && q2 <= q4 ) | 
| 271       arc[3] = ( y1 + y4 ) / 2; | 270       { | 
|  | 271         *max = q4; | 
|  | 272         break; | 
|  | 273       } | 
|  | 274     } | 
| 272 | 275 | 
| 273       arc += 3; | 276     q1 = p1; | 
| 274       goto Suite; | 277     q2 = p2; | 
|  | 278     q3 = p3; | 
|  | 279     q4 = p4; | 
| 275 | 280 | 
| 276    Test: | 281     /* for a conic segment to possibly reach new minimum     */ | 
| 277       if ( y1 < *min ) *min = y1; | 282     /* one of its off-points must be below the current value */ | 
| 278       if ( y4 > *max ) *max = y4; | 283     while ( q2 < *min || q3 < *min ) | 
| 279       arc -= 3; | 284     { | 
|  | 285       /* determine which half contains the minimum and split */ | 
|  | 286       if ( q1 + q2 < q3 + q4 ) /* first half */ | 
|  | 287       { | 
|  | 288         q4 = q4 + q3; | 
|  | 289         q3 = q3 + q2; | 
|  | 290         q2 = q2 + q1; | 
|  | 291         q4 = q4 + q3; | 
|  | 292         q3 = q3 + q2; | 
|  | 293         q4 = ( q4 + q3 ) / 8; | 
|  | 294         q3 = q3 / 4; | 
|  | 295         q2 = q2 / 2; | 
|  | 296       } | 
|  | 297       else                     /* second half */ | 
|  | 298       { | 
|  | 299         q1 = q1 + q2; | 
|  | 300         q2 = q2 + q3; | 
|  | 301         q3 = q3 + q4; | 
|  | 302         q1 = q1 + q2; | 
|  | 303         q2 = q2 + q3; | 
|  | 304         q1 = ( q1 + q2 ) / 8; | 
|  | 305         q2 = q2 / 4; | 
|  | 306         q3 = q3 / 2; | 
|  | 307       } | 
| 280 | 308 | 
| 281     Suite: | 309       /* check if either end reached the minimum */ | 
| 282       ; | 310       if ( q1 == q2 && q1 <= q3 ) | 
| 283     } while ( arc >= stack ); | 311       { | 
|  | 312         *min = q1; | 
|  | 313         break; | 
|  | 314       } | 
|  | 315       if ( q3 == q4 && q2 >= q4 ) | 
|  | 316       { | 
|  | 317         *min = q4; | 
|  | 318         break; | 
|  | 319       } | 
|  | 320     } | 
| 284   } | 321   } | 
| 285 | 322 | 
| 286 #else | 323 #else | 
| 287 | 324 | 
| 288   static void | 325   static void | 
| 289   test_cubic_extrema( FT_Pos    y1, | 326   test_cubic_extrema( FT_Pos    y1, | 
| 290                       FT_Pos    y2, | 327                       FT_Pos    y2, | 
| 291                       FT_Pos    y3, | 328                       FT_Pos    y3, | 
| 292                       FT_Pos    y4, | 329                       FT_Pos    y4, | 
| 293                       FT_Fixed  u, | 330                       FT_Fixed  u, | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 351       if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) | 388       if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) | 
| 352         return; | 389         return; | 
| 353     } | 390     } | 
| 354     else /* y1 > y4 */ | 391     else /* y1 > y4 */ | 
| 355     { | 392     { | 
| 356       /* descending arc test */ | 393       /* descending arc test */ | 
| 357       if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) | 394       if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) | 
| 358         return; | 395         return; | 
| 359     } | 396     } | 
| 360 | 397 | 
| 361     /* There are some split points.  Find them. */ | 398     /* There are some split points.  Find them.                        */ | 
|  | 399     /* We already made sure that a, b, and c below cannot be all zero. */ | 
| 362     { | 400     { | 
| 363       FT_Pos    a = y4 - 3*y3 + 3*y2 - y1; | 401       FT_Pos    a = y4 - 3*y3 + 3*y2 - y1; | 
| 364       FT_Pos    b = y3 - 2*y2 + y1; | 402       FT_Pos    b = y3 - 2*y2 + y1; | 
| 365       FT_Pos    c = y2 - y1; | 403       FT_Pos    c = y2 - y1; | 
| 366       FT_Pos    d; | 404       FT_Pos    d; | 
| 367       FT_Fixed  t; | 405       FT_Fixed  t; | 
|  | 406       FT_Int    shift; | 
| 368 | 407 | 
| 369 | 408 | 
| 370       /* We need to solve `ax^2+2bx+c' here, without floating points!      */ | 409       /* We need to solve `ax^2+2bx+c' here, without floating points!      */ | 
| 371       /* The trick is to normalize to a different representation in order  */ | 410       /* The trick is to normalize to a different representation in order  */ | 
| 372       /* to use our 16.16 fixed point routines.                            */ | 411       /* to use our 16.16 fixed-point routines.                            */ | 
| 373       /*                                                                   */ | 412       /*                                                                   */ | 
| 374       /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */ | 413       /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */ | 
| 375       /* These values must fit into a single 16.16 value.                  */ | 414       /* These values must fit into a single 16.16 value.                  */ | 
| 376       /*                                                                   */ | 415       /*                                                                   */ | 
| 377       /* We normalize a, b, and c to `8.16' fixed float values to ensure   */ | 416       /* We normalize a, b, and c to `8.16' fixed-point values to ensure   */ | 
| 378       /* that its product is held in a `16.16' value.                      */ | 417       /* that their product is held in a `16.16' value including the sign. */ | 
|  | 418       /* Necessarily, we need to shift `a', `b', and `c' so that the most  */ | 
|  | 419       /* significant bit of their absolute values is at position 22.       */ | 
|  | 420       /*                                                                   */ | 
|  | 421       /* This also means that we are using 23 bits of precision to compute */ | 
|  | 422       /* the zeros, independently of the range of the original polynomial  */ | 
|  | 423       /* coefficients.                                                     */ | 
|  | 424       /*                                                                   */ | 
|  | 425       /* This algorithm should ensure reasonably accurate values for the   */ | 
|  | 426       /* zeros.  Note that they are only expressed with 16 bits when       */ | 
|  | 427       /* computing the extrema (the zeros need to be in 0..1 exclusive     */ | 
|  | 428       /* to be considered part of the arc).                                */ | 
| 379 | 429 | 
|  | 430       shift = FT_MSB( FT_ABS( a ) | FT_ABS( b ) | FT_ABS( c ) ); | 
|  | 431 | 
|  | 432       if ( shift > 22 ) | 
| 380       { | 433       { | 
| 381         FT_ULong  t1, t2; | 434         shift -= 22; | 
| 382         int       shift = 0; |  | 
| 383 | 435 | 
|  | 436         /* this loses some bits of precision, but we use 23 of them */ | 
|  | 437         /* for the computation anyway                               */ | 
|  | 438         a >>= shift; | 
|  | 439         b >>= shift; | 
|  | 440         c >>= shift; | 
|  | 441       } | 
|  | 442       else | 
|  | 443       { | 
|  | 444         shift = 22 - shift; | 
| 384 | 445 | 
| 385         /* The following computation is based on the fact that for   */ | 446         a <<= shift; | 
| 386         /* any value `y', if `n' is the position of the most         */ | 447         b <<= shift; | 
| 387         /* significant bit of `abs(y)' (starting from 0 for the      */ | 448         c <<= shift; | 
| 388         /* least significant bit), then `y' is in the range          */ |  | 
| 389         /*                                                           */ |  | 
| 390         /*   -2^n..2^n-1                                             */ |  | 
| 391         /*                                                           */ |  | 
| 392         /* We want to shift `a', `b', and `c' concurrently in order  */ |  | 
| 393         /* to ensure that they all fit in 8.16 values, which maps    */ |  | 
| 394         /* to the integer range `-2^23..2^23-1'.                     */ |  | 
| 395         /*                                                           */ |  | 
| 396         /* Necessarily, we need to shift `a', `b', and `c' so that   */ |  | 
| 397         /* the most significant bit of its absolute values is at     */ |  | 
| 398         /* _most_ at position 23.                                    */ |  | 
| 399         /*                                                           */ |  | 
| 400         /* We begin by computing `t1' as the bitwise `OR' of the     */ |  | 
| 401         /* absolute values of `a', `b', `c'.                         */ |  | 
| 402 |  | 
| 403         t1  = (FT_ULong)( ( a >= 0 ) ? a : -a ); |  | 
| 404         t2  = (FT_ULong)( ( b >= 0 ) ? b : -b ); |  | 
| 405         t1 |= t2; |  | 
| 406         t2  = (FT_ULong)( ( c >= 0 ) ? c : -c ); |  | 
| 407         t1 |= t2; |  | 
| 408 |  | 
| 409         /* Now we can be sure that the most significant bit of `t1'  */ |  | 
| 410         /* is the most significant bit of either `a', `b', or `c',   */ |  | 
| 411         /* depending on the greatest integer range of the particular */ |  | 
| 412         /* variable.                                                 */ |  | 
| 413         /*                                                           */ |  | 
| 414         /* Next, we compute the `shift', by shifting `t1' as many    */ |  | 
| 415         /* times as necessary to move its MSB to position 23.  This  */ |  | 
| 416         /* corresponds to a value of `t1' that is in the range       */ |  | 
| 417         /* 0x40_0000..0x7F_FFFF.                                     */ |  | 
| 418         /*                                                           */ |  | 
| 419         /* Finally, we shift `a', `b', and `c' by the same amount.   */ |  | 
| 420         /* This ensures that all values are now in the range         */ |  | 
| 421         /* -2^23..2^23, i.e., they are now expressed as 8.16         */ |  | 
| 422         /* fixed-float numbers.  This also means that we are using   */ |  | 
| 423         /* 24 bits of precision to compute the zeros, independently  */ |  | 
| 424         /* of the range of the original polynomial coefficients.     */ |  | 
| 425         /*                                                           */ |  | 
| 426         /* This algorithm should ensure reasonably accurate values   */ |  | 
| 427         /* for the zeros.  Note that they are only expressed with    */ |  | 
| 428         /* 16 bits when computing the extrema (the zeros need to     */ |  | 
| 429         /* be in 0..1 exclusive to be considered part of the arc).   */ |  | 
| 430 |  | 
| 431         if ( t1 == 0 )  /* all coefficients are 0! */ |  | 
| 432           return; |  | 
| 433 |  | 
| 434         if ( t1 > 0x7FFFFFUL ) |  | 
| 435         { |  | 
| 436           do |  | 
| 437           { |  | 
| 438             shift++; |  | 
| 439             t1 >>= 1; |  | 
| 440 |  | 
| 441           } while ( t1 > 0x7FFFFFUL ); |  | 
| 442 |  | 
| 443           /* this loses some bits of precision, but we use 24 of them */ |  | 
| 444           /* for the computation anyway                               */ |  | 
| 445           a >>= shift; |  | 
| 446           b >>= shift; |  | 
| 447           c >>= shift; |  | 
| 448         } |  | 
| 449         else if ( t1 < 0x400000UL ) |  | 
| 450         { |  | 
| 451           do |  | 
| 452           { |  | 
| 453             shift++; |  | 
| 454             t1 <<= 1; |  | 
| 455 |  | 
| 456           } while ( t1 < 0x400000UL ); |  | 
| 457 |  | 
| 458           a <<= shift; |  | 
| 459           b <<= shift; |  | 
| 460           c <<= shift; |  | 
| 461         } |  | 
| 462       } | 449       } | 
| 463 | 450 | 
| 464       /* handle a == 0 */ | 451       /* handle a == 0 */ | 
| 465       if ( a == 0 ) | 452       if ( a == 0 ) | 
| 466       { | 453       { | 
| 467         if ( b != 0 ) | 454         if ( b != 0 ) | 
| 468         { | 455         { | 
| 469           t = - FT_DivFix( c, b ) / 2; | 456           t = - FT_DivFix( c, b ) / 2; | 
| 470           test_cubic_extrema( y1, y2, y3, y4, t, min, max ); | 457           test_cubic_extrema( y1, y2, y3, y4, t, min, max ); | 
| 471         } | 458         } | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 574   FT_Outline_Get_BBox( FT_Outline*  outline, | 561   FT_Outline_Get_BBox( FT_Outline*  outline, | 
| 575                        FT_BBox     *abbox ) | 562                        FT_BBox     *abbox ) | 
| 576   { | 563   { | 
| 577     FT_BBox     cbox; | 564     FT_BBox     cbox; | 
| 578     FT_BBox     bbox; | 565     FT_BBox     bbox; | 
| 579     FT_Vector*  vec; | 566     FT_Vector*  vec; | 
| 580     FT_UShort   n; | 567     FT_UShort   n; | 
| 581 | 568 | 
| 582 | 569 | 
| 583     if ( !abbox ) | 570     if ( !abbox ) | 
| 584       return FT_Err_Invalid_Argument; | 571       return FT_THROW( Invalid_Argument ); | 
| 585 | 572 | 
| 586     if ( !outline ) | 573     if ( !outline ) | 
| 587       return FT_Err_Invalid_Outline; | 574       return FT_THROW( Invalid_Outline ); | 
| 588 | 575 | 
| 589     /* if outline is empty, return (0,0,0,0) */ | 576     /* if outline is empty, return (0,0,0,0) */ | 
| 590     if ( outline->n_points == 0 || outline->n_contours <= 0 ) | 577     if ( outline->n_points == 0 || outline->n_contours <= 0 ) | 
| 591     { | 578     { | 
| 592       abbox->xMin = abbox->xMax = 0; | 579       abbox->xMin = abbox->xMax = 0; | 
| 593       abbox->yMin = abbox->yMax = 0; | 580       abbox->yMin = abbox->yMax = 0; | 
| 594       return 0; | 581       return 0; | 
| 595     } | 582     } | 
| 596 | 583 | 
| 597     /* We compute the control box as well as the bounding box of  */ | 584     /* We compute the control box as well as the bounding box of  */ | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 653       *abbox = user.bbox; | 640       *abbox = user.bbox; | 
| 654     } | 641     } | 
| 655     else | 642     else | 
| 656       *abbox = bbox; | 643       *abbox = bbox; | 
| 657 | 644 | 
| 658     return FT_Err_Ok; | 645     return FT_Err_Ok; | 
| 659   } | 646   } | 
| 660 | 647 | 
| 661 | 648 | 
| 662 /* END */ | 649 /* END */ | 
| OLD | NEW | 
|---|