71 median_cell_height_(0),
72 median_cell_width_(0),
230 int column_start,
int column_end) {
232 ASSERT_HOST(0 <= column_start && column_start <= column_end &&
236 for (
int row = row_start; row <= row_end; ++row) {
239 for (
int col = column_start; col <= column_end; ++col) {
271 gsearch.SetUniqueMode(
true);
272 gsearch.StartRectSearch(kCellBox);
273 double area_covered = 0;
275 while ((text = gsearch.NextRectSearch()) !=
NULL) {
279 return MIN(1.0, area_covered / kCellBox.
area());
283 #ifndef GRAPHICS_DISABLED
370 if (left_sides.
length() == 0 || right_sides.
length() == 0)
436 if (bottom_sides.
length() == 0 || top_sides.
length() == 0)
478 bool decrease)
const {
495 bool decrease)
const {
512 const int kMaxCellHeight = 1000;
513 const int kMaxCellWidth = 1000;
514 STATS height_stats(0, kMaxCellHeight + 1);
515 STATS width_stats(0, kMaxCellWidth + 1);
591 if (min_list.
length() == 0)
600 int stacked_partitions = 0;
605 while (min_index < min_list.
length()) {
607 if (min_list[min_index] < max_list[max_index]) {
608 ++stacked_partitions;
610 stacked_partitions > max_merged) {
611 int mid = (last_cross_position + min_list[min_index]) / 2;
618 --stacked_partitions;
620 stacked_partitions <= max_merged) {
621 last_cross_position = max_list[max_index];
636 vertical_box.
set_left(x - kGridSize);
661 horizontal_box.
set_top(y + kGridSize);
755 TBOX line_bound = guess_box;
773 int vertical_count = 0;
774 int horizontal_count = 0;
818 int old_area = bounding_box->
area();
823 changed = (bounding_box->
area() > old_area);
835 bool first_line =
true;
869 TBOX best_box = guess_box;
872 TBOX adjusted = guess_box;
877 const int kMidGuessY = (guess_box.
bottom() + guess_box.
top()) / 2;
882 bool found_good_border =
false;
897 int previous_below = 0;
898 const int kMaxChances = 10;
899 int chances = kMaxChances;
900 while (bottom != last_bottom) {
920 chances = kMaxChances;
929 found_good_border =
true;
940 last_bottom = bottom;
944 if (!found_good_border)
948 found_good_border =
false;
952 int previous_above = 0;
953 chances = kMaxChances;
956 while (last_top != top) {
967 chances = kMaxChances;
972 table->
row_height(last_row) < max_row_height)) {
976 found_good_border =
true;
992 if (!found_good_border)
1012 bool top_to_bottom) {
1025 if (top_to_bottom && (last_y >= y || last_y <= text_box.
top())) {
1026 last_y =
MIN(last_y, text_box.
bottom());
1029 if (!top_to_bottom && (last_y <= y || last_y >= text_box.
bottom())) {
1030 last_y =
MAX(last_y, text_box.
top());
1049 double threshold = 0.0;
const int kLinedTableMinVerticalLines
ColPartitionGrid * text_grid_
void set_text_grid(ColPartitionGrid *text)
int row_height(int row) const
void set_min_height(int height)
bool VerifyLinedTableCells()
const TBOX & bounding_box() const
void set_line_grid(ColPartitionGrid *lines)
ColPartitionGrid * line_grid_
bool VerifyWhitespacedTable()
void FindWhitespacedRows()
BBC * NextSideSearch(bool right_to_left)
bool RecognizeLinedTable(const TBOX &guess_box, StructuredTable *table)
GenericVectorEqEq< int > cell_x_
const int kLinedTableMinHorizontalLines
ColPartitionGrid * text_grid_
bool FindWhitespacedStructure()
void UpdateMargins(ColPartitionGrid *grid)
int CountHorizontalIntersections(int y)
bool FindLinedStructure()
int CountFilledCellsInColumn(int column)
bool IsHorizontalType() const
int NextHorizontalSplit(int left, int right, int y, bool top_to_bottom)
void StartRectSearch(const TBOX &rect)
void add(inT32 value, inT32 count)
void set_line_grid(ColPartitionGrid *lines)
bool HasSignificantLines(const TBOX &guess)
const double kHorizontalSpacing
bool IsHorizontalLine() const
bool RecognizeWhitespacedTable(const TBOX &guess_box, StructuredTable *table)
StructuredTable * RecognizeTable(const TBOX &guess_box)
int CountPartitions(const TBOX &box)
void set_min_width(int width)
const int kGoodRowNumberOfColumnsSmallSize
const double kMarginFactor
const double kRequiredColumns
void set_max_text_height(int height)
int column_width(int column) const
bool FindLinesBoundingBoxIteration(TBOX *bounding_box)
GenericVectorEqEq< int > cell_y_
void FindWhitespacedColumns()
bool FindLinesBoundingBox(TBOX *bounding_box)
void StartVerticalSearch(int xmin, int xmax, int y)
void StartSideSearch(int x, int ymin, int ymax)
bool DoesPartitionFit(const ColPartition &part) const
const double kVerticalSpacing
const double kMinFilledArea
bool VerifyRowFilled(int row)
const double kGoodRowNumberOfColumnsSmall[]
void SetUniqueMode(bool mode)
static bool IsWeakTableRow(StructuredTable *table, int row)
const int kCellSplitRowThreshold
const int kCellSplitColumnThreshold
int CountVerticalIntersections(int x)
bool IsVerticalLine() const
void Display(ScrollView *window, ScrollView::Color color)
TBOX intersection(const TBOX &box) const
double CalculateCellFilledPercentage(int row, int column)
int FindVerticalMargin(ColPartitionGrid *grid, int start_x, bool decrease) const
int CountFilledCellsInRow(int row)
static void FindCellSplitLocations(const GenericVector< int > &min_list, const GenericVector< int > &max_list, int max_merged, GenericVector< int > *locations)
BBC * NextVerticalSearch(bool top_to_bottom)
int FindHorizontalMargin(ColPartitionGrid *grid, int start_y, bool decrease) const
const double kGoodRowNumberOfColumnsLarge
void set_max_text_height(int height)
void set_text_grid(ColPartitionGrid *text)
const TBOX & bounding_box() const
ColPartitionGrid * line_grid_
void set_bounding_box(const TBOX &box)