416 {
418 int left = box.left();
419 int width = box.width();
420 int bottom = box.bottom();
422 return bottom;
423 }
424
425 std::vector<int> y_mins(width + 1, box.top());
426 C_OUTLINE_IT it(&outlines);
427 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
428 C_OUTLINE *outline = it.data();
429 ICOORD pos = outline->start_pos();
430 for (int s = 0; s < outline->pathlength(); ++s) {
431 if (pos.y() < y_mins[pos.x() - left]) {
432 y_mins[pos.x() - left] = pos.y();
433 }
434 pos += outline->step(s);
435 }
436 }
437
438 int bottom_extent = 0;
439 for (
int x = 0;
x <= width; ++
x) {
440 if (y_mins[
x] == bottom || y_mins[
x] == bottom + 1) {
441 ++bottom_extent;
442 }
443 }
444
445 int best_min = box.top();
446 int prev_run = 0;
447 int prev_y = box.top();
448 int prev_prev_y = box.top();
449 for (
int x = 0;
x < width;
x += prev_run) {
450
451 int y_at_x = y_mins[
x];
452 int run = 1;
453 while (
x + run <= width && y_mins[
x + run] == y_at_x) {
454 ++run;
455 }
456 if (y_at_x > bottom + 1) {
457
458 int total_run = run;
459
460 while (
x + total_run <= width &&
461 (y_mins[
x + total_run] == y_at_x || y_mins[
x + total_run] == y_at_x + 1)) {
462 ++total_run;
463 }
464
465 if (prev_prev_y > y_at_x + 1 ||
x + total_run > width || y_mins[
x + total_run] > y_at_x + 1) {
466
467
468 if (prev_run > 0 && prev_y == y_at_x + 1) {
469 total_run += prev_run;
470 }
471 if (total_run > bottom_extent && y_at_x < best_min) {
472 best_min = y_at_x;
473 }
474 }
475 }
476 prev_run = run;
477 prev_prev_y = prev_y;
478 prev_y = y_at_x;
479 }
480 return best_min == box.top() ? bottom : best_min;
481}
const double kMaxPerimeterWidthRatio
TBOX bounding_box() const