887 TBOX best_box = guess_box;
890 TBOX adjusted = guess_box;
895 const int kMidGuessY = (guess_box.bottom() + guess_box.top()) / 2;
898 unsigned best_cols = 0;
900 bool found_good_border =
false;
905 int last_bottom = INT32_MAX;
910 adjusted.set_top(top);
915 int previous_below = 0;
916 const int kMaxChances = 10;
917 int chances = kMaxChances;
918 while (bottom != last_bottom) {
919 adjusted.set_bottom(bottom);
924 table->set_bounding_box(adjusted);
925 if (table->FindWhitespacedStructure() &&
938 chances = kMaxChances;
939 double max_row_height =
kMaxRowSize * table->median_cell_height();
941 table->space_below() >= previous_below) ||
942 (table->CountFilledCellsInRow(0) > 1 && table->row_height(0) < max_row_height)) {
943 best_box.set_bottom(bottom);
944 best_below = table->space_below();
945 best_cols = std::max(table->column_count(), best_cols);
946 found_good_border =
true;
949 previous_below = table->space_below();
958 last_bottom = bottom;
961 if (!found_good_border) {
966 found_good_border =
false;
967 int last_top = INT32_MIN;
970 int previous_above = 0;
971 chances = kMaxChances;
973 adjusted.set_bottom(best_box.bottom());
974 while (last_top != top) {
975 adjusted.set_top(top);
977 table->set_bounding_box(adjusted);
978 if (table->FindWhitespacedStructure() &&
980 int last_row = table->row_count() - 1;
985 chances = kMaxChances;
986 double max_row_height =
kMaxRowSize * table->median_cell_height();
988 table->space_above() >= previous_above) ||
989 (table->CountFilledCellsInRow(last_row) > 1 &&
990 table->row_height(last_row) < max_row_height)) {
991 best_box.set_top(top);
992 best_above = table->space_above();
993 best_cols = std::max(table->column_count(), best_cols);
994 found_good_border =
true;
997 previous_above = table->space_above();
1010 if (!found_good_border) {
1016 if (best_box.null_box()) {
1021 table->set_bounding_box(best_box);
1022 return table->FindWhitespacedStructure();
const double kRequiredColumns
const double kMarginFactor
static bool IsWeakTableRow(StructuredTable *table, int row)
int NextHorizontalSplit(int left, int right, int y, bool top_to_bottom)