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;
int CountFilledCellsInRow(int row)
GenericVectorEqEq< int > cell_x_
int CountFilledCellsInColumn(int column)
bool HasSignificantLines(const TBOX &guess)
double CalculateCellFilledPercentage(int row, int column)
const int kGoodRowNumberOfColumnsSmallSize
bool IsHorizontalType() const
const double kGoodRowNumberOfColumnsSmall[]
const double kMarginFactor
int NextHorizontalSplit(int left, int right, int y, bool top_to_bottom)
BBC * NextVerticalSearch(bool top_to_bottom)
ColPartitionGrid * text_grid_
const TBOX & bounding_box() const
bool FindWhitespacedStructure()
const double kVerticalSpacing
bool DoesPartitionFit(const ColPartition &part) const
int FindVerticalMargin(ColPartitionGrid *grid, int start_x, bool decrease) const
static void FindCellSplitLocations(const GenericVector< int > &min_list, const GenericVector< int > &max_list, int max_merged, GenericVector< int > *locations)
void add(inT32 value, inT32 count)
void set_bounding_box(const TBOX &box)
GenericVectorEqEq< int > cell_y_
const double kGoodRowNumberOfColumnsLarge
bool FindLinesBoundingBox(TBOX *bounding_box)
BBC * NextSideSearch(bool right_to_left)
ColPartitionGrid * line_grid_
bool RecognizeWhitespacedTable(const TBOX &guess_box, StructuredTable *table)
const int kLinedTableMinVerticalLines
void set_max_text_height(int height)
int CountVerticalIntersections(int x)
const TBOX & bounding_box() const
void SetUniqueMode(bool mode)
bool FindLinedStructure()
int FindHorizontalMargin(ColPartitionGrid *grid, int start_y, bool decrease) const
void set_line_grid(ColPartitionGrid *lines)
const double kRequiredColumns
bool IsHorizontalLine() const
bool VerifyLinedTableCells()
bool RecognizeLinedTable(const TBOX &guess_box, StructuredTable *table)
const double kHorizontalSpacing
ColPartitionGrid * line_grid_
void set_line_grid(ColPartitionGrid *lines)
void set_min_height(int height)
const double kMinFilledArea
void set_min_width(int width)
bool FindLinesBoundingBoxIteration(TBOX *bounding_box)
void StartSideSearch(int x, int ymin, int ymax)
void set_text_grid(ColPartitionGrid *text)
void set_text_grid(ColPartitionGrid *text)
void StartRectSearch(const TBOX &rect)
void UpdateMargins(ColPartitionGrid *grid)
int column_width(int column) const
TBOX intersection(const TBOX &box) const
static bool IsWeakTableRow(StructuredTable *table, int row)
void set_max_text_height(int height)
int row_height(int row) const
void FindWhitespacedRows()
StructuredTable * RecognizeTable(const TBOX &guess_box)
int CountHorizontalIntersections(int y)
const int kCellSplitColumnThreshold
void Rectangle(int x1, int y1, int x2, int y2)
const int kCellSplitRowThreshold
bool VerifyRowFilled(int row)
bool IsVerticalLine() const
void Line(int x1, int y1, int x2, int y2)
const int kLinedTableMinHorizontalLines
void Display(ScrollView *window, ScrollView::Color color)
int CountPartitions(const TBOX &box)
bool VerifyWhitespacedTable()
ColPartitionGrid * text_grid_
void FindWhitespacedColumns()
void StartVerticalSearch(int xmin, int xmax, int y)