75 median_cell_height_(0),
76 median_cell_width_(0),
234 int column_start,
int column_end) {
236 ASSERT_HOST(0 <= column_start && column_start <= column_end &&
240 for (
int row = row_start; row <= row_end; ++row) {
243 for (
int col = column_start; col <= column_end; ++col) {
275 gsearch.SetUniqueMode(
true);
276 gsearch.StartRectSearch(kCellBox);
277 double area_covered = 0;
279 while ((text = gsearch.NextRectSearch()) != NULL) {
283 const inT32 current_area = kCellBox.
area();
284 if (current_area == 0) {
287 return MIN(1.0, area_covered / current_area);
291 #ifndef GRAPHICS_DISABLED 378 if (left_sides.
length() == 0 || right_sides.
length() == 0)
444 if (bottom_sides.
length() == 0 || top_sides.
length() == 0)
486 bool decrease)
const {
503 bool decrease)
const {
520 const int kMaxCellHeight = 1000;
521 const int kMaxCellWidth = 1000;
522 STATS height_stats(0, kMaxCellHeight + 1);
523 STATS width_stats(0, kMaxCellWidth + 1);
599 if (min_list.
length() == 0)
608 int stacked_partitions = 0;
613 while (min_index < min_list.
length()) {
615 if (min_list[min_index] < max_list[max_index]) {
616 ++stacked_partitions;
618 stacked_partitions > max_merged) {
619 int mid = (last_cross_position + min_list[min_index]) / 2;
626 --stacked_partitions;
628 stacked_partitions <= max_merged) {
629 last_cross_position = max_list[max_index];
644 vertical_box.
set_left(x - kGridSize);
669 horizontal_box.
set_top(y + kGridSize);
763 TBOX line_bound = guess_box;
781 int vertical_count = 0;
782 int horizontal_count = 0;
826 int old_area = bounding_box->
area();
831 changed = (bounding_box->
area() > old_area);
843 bool first_line =
true;
877 TBOX best_box = guess_box;
880 TBOX adjusted = guess_box;
885 const int kMidGuessY = (guess_box.
bottom() + guess_box.
top()) / 2;
890 bool found_good_border =
false;
905 int previous_below = 0;
906 const int kMaxChances = 10;
907 int chances = kMaxChances;
908 while (bottom != last_bottom) {
928 chances = kMaxChances;
937 found_good_border =
true;
948 last_bottom = bottom;
952 if (!found_good_border)
956 found_good_border =
false;
960 int previous_above = 0;
961 chances = kMaxChances;
964 while (last_top != top) {
975 chances = kMaxChances;
980 table->
row_height(last_row) < max_row_height)) {
984 found_good_border =
true;
1000 if (!found_good_border)
1020 bool top_to_bottom) {
1033 if (top_to_bottom && (last_y >= y || last_y <= text_box.
top())) {
1034 last_y =
MIN(last_y, text_box.
bottom());
1037 if (!top_to_bottom && (last_y <= y || last_y >= text_box.
bottom())) {
1038 last_y =
MAX(last_y, text_box.
top());
1057 double threshold = 0.0;
void set_line_grid(ColPartitionGrid *lines)
const int kCellSplitRowThreshold
bool FindLinesBoundingBox(TBOX *bounding_box)
const TBOX & bounding_box() const
const double kMarginFactor
ColPartitionGrid * line_grid_
void set_line_grid(ColPartitionGrid *lines)
const double kGoodRowNumberOfColumnsSmall[]
void Display(ScrollView *window, ScrollView::Color color)
ColPartitionGrid * text_grid_
const int kCellSplitColumnThreshold
bool RecognizeWhitespacedTable(const TBOX &guess_box, StructuredTable *table)
const double kRequiredColumns
bool FindLinesBoundingBoxIteration(TBOX *bounding_box)
BBC * NextVerticalSearch(bool top_to_bottom)
void set_min_height(int height)
void Line(int x1, int y1, int x2, int y2)
void add(inT32 value, inT32 count)
void SetUniqueMode(bool mode)
void set_max_text_height(int height)
void set_min_width(int width)
void StartVerticalSearch(int xmin, int xmax, int y)
bool RecognizeLinedTable(const TBOX &guess_box, StructuredTable *table)
const double kMinFilledArea
const double kGoodRowNumberOfColumnsLarge
int CountVerticalIntersections(int x)
void set_text_grid(ColPartitionGrid *text)
bool FindWhitespacedStructure()
bool VerifyLinedTableCells()
bool DoesPartitionFit(const ColPartition &part) const
void StartSideSearch(int x, int ymin, int ymax)
bool VerifyWhitespacedTable()
void FindWhitespacedRows()
int FindHorizontalMargin(ColPartitionGrid *grid, int start_y, bool decrease) const
void set_bounding_box(const TBOX &box)
ColPartitionGrid * text_grid_
const int kGoodRowNumberOfColumnsSmallSize
StructuredTable * RecognizeTable(const TBOX &guess_box)
int FindVerticalMargin(ColPartitionGrid *grid, int start_x, bool decrease) const
GenericVectorEqEq< int > cell_x_
BBC * NextSideSearch(bool right_to_left)
ColPartitionGrid * line_grid_
bool IsHorizontalType() const
bool HasSignificantLines(const TBOX &guess)
int NextHorizontalSplit(int left, int right, int y, bool top_to_bottom)
bool IsHorizontalLine() const
int column_width(int column) const
void set_text_grid(ColPartitionGrid *text)
void Rectangle(int x1, int y1, int x2, int y2)
const double kHorizontalSpacing
void FindWhitespacedColumns()
bool VerifyRowFilled(int row)
const int kLinedTableMinVerticalLines
static void FindCellSplitLocations(const GenericVector< int > &min_list, const GenericVector< int > &max_list, int max_merged, GenericVector< int > *locations)
int CountFilledCellsInColumn(int column)
bool IsVerticalLine() const
int row_height(int row) const
void set_max_text_height(int height)
const int kLinedTableMinHorizontalLines
int CountFilledCellsInRow(int row)
int CountHorizontalIntersections(int y)
const double kVerticalSpacing
static bool IsWeakTableRow(StructuredTable *table, int row)
GenericVectorEqEq< int > cell_y_
int CountPartitions(const TBOX &box)
TBOX intersection(const TBOX &box) const
const TBOX & bounding_box() const
void StartRectSearch(const TBOX &rect)
void UpdateMargins(ColPartitionGrid *grid)
bool FindLinedStructure()
double CalculateCellFilledPercentage(int row, int column)