Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: src/base/ftbbox.c

Issue 89753003: Update freetype to latest version of ASOP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src/third_party/freetype.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/base/ftadvanc.c ('k') | src/base/ftbitmap.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 */
OLDNEW
« no previous file with comments | « src/base/ftadvanc.c ('k') | src/base/ftbitmap.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698