20#ifndef TESSERACT_TEXTORD_COLPARTITION_H_
21#define TESSERACT_TEXTORD_COLPARTITION_H_
42class WorkingPartSet_LIST;
85 const ICOORD &vertical,
int left,
86 int bottom,
int right,
int top);
103 ColPartition_LIST *big_part_list);
109 return bounding_box_;
115 left_margin_ = margin;
118 return right_margin_;
121 right_margin_ = margin;
127 return median_bottom_;
133 return median_right_;
136 return median_height_;
139 median_height_ = height;
142 return median_width_;
145 median_width_ = width;
160 return good_blob_score_;
169 return left_key_tab_;
175 return right_key_tab_;
190 return boxes_.length();
196 return &upper_partners_;
199 return &lower_partners_;
202 working_set_ = working_set;
208 block_owned_ = owned;
211 return desperately_merged_;
220 return bottom_spacing_;
223 bottom_spacing_ = spacing;
229 top_spacing_ = spacing;
234 type_before_table_ = type_;
240 type_ = type_before_table_;
244 return inside_table_column_;
247 inside_table_column_ = val;
250 return nearest_neighbor_above_;
253 nearest_neighbor_above_ = part;
256 return nearest_neighbor_below_;
259 nearest_neighbor_below_ = part;
265 space_above_ = space;
271 space_below_ = space;
274 return space_to_left_;
277 space_to_left_ = space;
280 return space_to_right_;
283 space_to_right_ = space;
298 owns_blobs_ = owns_blobs;
305 return (bounding_box_.top() + bounding_box_.bottom()) / 2;
309 return (median_top_ + median_bottom_) / 2;
313 return (bounding_box_.left() + bounding_box_.right()) / 2;
320 int XAtY(
int sort_key,
int y)
const {
325 return (right_key - left_key) / vertical_.y();
329 return KeyWidth(left_key_, right_key_);
333 return SortKey(bounding_box_.left(), MidY());
337 return SortKey(bounding_box_.right(), MidY());
341 return XAtY(left_key_,
y);
345 return XAtY(right_key_,
y);
350 return bounding_box_.right() < other.bounding_box_.
right();
354 return LeftAtY(
y) - 1 <=
x &&
x <= RightAtY(
y) + 1;
358 return boxes_.empty();
362 return boxes_.singleton();
366 return bounding_box_.x_overlap(other.bounding_box_);
371 return bounding_box_.y_gap(other.bounding_box_) < 0;
376 if (median_bottom_ == INT32_MAX || other.median_bottom_ == INT32_MAX) {
379 return std::min(median_top_, other.median_top_) -
380 std::max(median_bottom_, other.median_bottom_);
385 return std::min(median_right_, other.median_right_) -
386 std::max(median_left_, other.median_left_);
391 if (median_bottom_ == INT32_MAX || other.median_bottom_ == INT32_MAX) {
394 int overlap = VCoreOverlap(other);
395 int height = std::min(median_top_ - median_bottom_,
396 other.median_top_ - other.median_bottom_);
397 return overlap * 3 > height;
402 return left_margin_ <= other.bounding_box_.
left() &&
403 bounding_box_.left() >= other.left_margin_ &&
404 bounding_box_.right() <= other.right_margin_ &&
405 right_margin_ >= other.bounding_box_.
right();
410 return TypesMatch(blob_type_, other.blob_type_);
419 return (type1 == type2 ||
455 return IsVerticalType() && IsLineType();
460 return IsHorizontalType() && IsLineType();
489 void DisownBoxesNoAssert();
494 bool ReleaseNonLeaderBoxes();
503 void ReflectInYAxis();
517 bool MatchingTextColor(
const ColPartition &other)
const;
524 bool ConfirmNoTabViolation(
const ColPartition &other)
const;
528 double fractional_tolerance,
529 double constant_tolerance)
const;
532 bool OKDiacriticMerge(
const ColPartition &candidate,
bool debug)
const;
537 void SetLeftTab(
const TabVector *tab_vector);
538 void SetRightTab(
const TabVector *tab_vector);
542 void CopyLeftTab(
const ColPartition &src,
bool take_box);
543 void CopyRightTab(
const ColPartition &src,
bool take_box);
546 int LeftBlobRule()
const;
548 int RightBlobRule()
const;
558 const float density);
561 void ComputeSpecialBlobsDensity();
582 int ok_box_overlap,
bool debug);
599 void ComputeLimits();
602 int CountOverlappingBoxes(
const TBOX &box);
616 void ColumnRange(
int resolution,
ColPartitionSet *columns,
int *first_col,
628 bool MarkAsLeaderIfMonospaced();
633 void SetRegionAndFlowTypesFromProjectionValue(
int value);
641 bool HasGoodBaseline();
645 void AddToWorkingSet(
const ICOORD &bleft,
const ICOORD &tright,
646 int resolution, ColPartition_LIST *used_parts,
647 WorkingPartSet_LIST *working_set);
655 static void LineSpacingBlocks(
const ICOORD &bleft,
const ICOORD &tright,
656 int resolution, ColPartition_LIST *block_parts,
657 ColPartition_LIST *used_parts,
658 BLOCK_LIST *completed_blocks,
659 TO_BLOCK_LIST *to_blocks);
663 ColPartition_LIST *block_parts,
664 ColPartition_LIST *used_parts);
670 ColPartition_LIST *block_parts,
671 ColPartition_LIST *used_parts);
685#ifndef GRAPHICS_DISABLED
696 void SmoothPartnerRun(
int working_set_count);
715 int mid_y1 = part1->bounding_box_.
y_middle();
716 int mid_y2 = part2->bounding_box_.
y_middle();
717 if ((part2->bounding_box_.
bottom() <= mid_y1 &&
718 mid_y1 <= part2->bounding_box_.
top()) ||
719 (part1->bounding_box_.
bottom() <= mid_y2 &&
720 mid_y2 <= part1->bounding_box_.
top())) {
725 return mid_y2 - mid_y1;
730 first_column_ = column;
733 last_column_ = column;
740 void RefinePartnersInternal(
bool upper,
bool get_desperate,
744 void RefinePartnersByType(
bool upper, ColPartition_CLIST *partners);
749 void RefinePartnerShortcuts(
bool upper, ColPartition_CLIST *partners);
756 void RefineTextPartnersByMerge(
bool upper,
bool desperate,
757 ColPartition_CLIST *partners,
760 void RefinePartnersByOverlap(
bool upper, ColPartition_CLIST *partners);
768 static void SmoothSpacings(
int resolution,
int page_height,
769 ColPartition_LIST *parts);
774 static bool OKSpacingBlip(
int resolution,
int median_spacing,
779 bool SpacingEqual(
int spacing,
int resolution)
const;
783 bool SpacingsEqual(
const ColPartition &other,
int resolution)
const;
788 bool SummedSpacingOK(
const ColPartition &other,
int spacing,
789 int resolution)
const;
793 int BottomSpacingMargin(
int resolution)
const;
797 int TopSpacingMargin(
int resolution)
const;
809 static void LeftEdgeRun(ColPartition_IT *part_it,
ICOORD *start,
ICOORD *end);
816 static void RightEdgeRun(ColPartition_IT *part_it,
ICOORD *start,
823 int left_margin_ = 0;
825 int right_margin_ = 0;
829 int median_bottom_ = 0;
832 int median_height_ = 0;
834 int median_left_ = 0;
835 int median_right_ = 0;
837 int median_width_ = 0;
842 int good_blob_score_ = 0;
844 bool good_width_ =
false;
846 bool good_column_ =
false;
848 bool left_key_tab_ =
false;
850 bool right_key_tab_ =
false;
864 BLOBNBOX_CLIST boxes_;
866 ColPartition_CLIST upper_partners_;
868 ColPartition_CLIST lower_partners_;
874 bool last_add_was_vertical_ =
false;
877 bool block_owned_ =
false;
880 bool desperately_merged_ =
false;
881 bool owns_blobs_ =
true;
889 int first_column_ = -1;
890 int last_column_ = -1;
893 int top_spacing_ = 0;
894 int bottom_spacing_ = 0;
900 int space_above_ = 0;
901 int space_below_ = 0;
902 int space_to_left_ = 0;
903 int space_to_right_ = 0;
914 bool inside_table_column_ =
false;
#define CLISTIZEH(CLASSNAME)
#define ELIST2IZEH(CLASSNAME)
bool PTIsLineType(PolyBlockType type)
std::function< bool(int)> WidthCallback
bool PTIsImageType(PolyBlockType type)
bool PTIsPulloutType(PolyBlockType type)
bool PTIsTextType(PolyBlockType type)
std::string Print(const T &value)
static bool IsLineType(BlobRegionType type)
static bool UnMergeableType(BlobRegionType type)
TDimension bottom() const
int KeyWidth(int left_key, int right_key) const
void set_space_to_left(int space)
BlobTextFlowType flow() const
static bool TypesMatch(BlobRegionType type1, BlobRegionType type2)
bool TypesMatch(const ColPartition &other) const
bool IsHorizontalLine() const
PolyBlockType type() const
void set_side_step(int step)
void set_right_margin(int margin)
ColPartition_CLIST * upper_partners()
int median_bottom() const
bool inside_table_column()
void set_working_set(WorkingPartSet *working_set)
bool VOverlaps(const ColPartition &other) const
int bottom_spacing() const
void set_left_margin(int margin)
bool IsVerticalLine() const
bool IsPulloutType() const
bool VSignificantCoreOverlap(const ColPartition &other) const
void set_nearest_neighbor_above(ColPartition *part)
BlobRegionType blob_type() const
void set_blob_type(BlobRegionType t)
int VCoreOverlap(const ColPartition &other) const
void set_median_width(int width)
const TBOX & bounding_box() const
void set_nearest_neighbor_below(ColPartition *part)
int HCoreOverlap(const ColPartition &other) const
int XAtY(int sort_key, int y) const
int space_to_left() const
bool IsVerticalType() const
bool HOverlaps(const ColPartition &other) const
bool left_key_tab() const
ColPartitionSet * column_set() const
ColPartition * nearest_neighbor_above() const
void set_space_above(int space)
int good_blob_score() const
void set_vertical(const ICOORD &v)
bool right_key_tab() const
void set_median_height(int height)
bool WithinSameMargins(const ColPartition &other) const
void set_inside_table_column(bool val)
void set_owns_blobs(bool owns_blobs)
void set_type(PolyBlockType t)
void set_space_to_right(int space)
static bool TypesSimilar(PolyBlockType type1, PolyBlockType type2)
int space_to_right() const
void set_last_column(int column)
void set_bottom_spacing(int spacing)
bool desperately_merged() const
ColPartition_CLIST * lower_partners()
int SortKey(int x, int y) const
void set_space_below(int space)
bool IsLeftOf(const ColPartition &other) const
bool IsUnMergeableType() const
void set_first_column(int column)
void set_top_spacing(int spacing)
int RightAtY(int y) const
void set_block_owned(bool owned)
bool ColumnContains(int x, int y) const
static int SortByBBox(const void *p1, const void *p2)
bool IsHorizontalType() const
ColPartition * nearest_neighbor_below() const
int median_height() const
void set_flow(BlobTextFlowType f)
static int SortKey(const ICOORD &vertical, int x, int y)