20 #ifndef TESSERACT_TEXTORD_COLPARTITION_H_
21 #define TESSERACT_TEXTORD_COLPARTITION_H_
42 class WorkingPartSet_LIST;
104 ColPartition_LIST* big_part_list);
110 return bounding_box_;
116 left_margin_ = margin;
119 return right_margin_;
122 right_margin_ = margin;
128 return median_bottom_;
134 return median_right_;
137 return median_height_;
140 median_height_ = height;
143 return median_width_;
146 median_width_ = width;
161 return good_blob_score_;
170 return left_key_tab_;
176 return right_key_tab_;
191 return boxes_.length();
197 return &upper_partners_;
200 return &lower_partners_;
203 working_set_ = working_set;
209 block_owned_ = owned;
212 return desperately_merged_;
221 return bottom_spacing_;
224 bottom_spacing_ = spacing;
230 top_spacing_ = spacing;
235 type_before_table_ = type_;
241 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;
557 void SetSpecialBlobsDensity(
561 void ComputeSpecialBlobsDensity();
582 int ok_box_overlap,
bool debug);
599 void ComputeLimits();
602 int CountOverlappingBoxes(
const TBOX& box);
617 int* first_col,
int* last_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,
657 ColPartition_LIST* block_parts,
658 ColPartition_LIST* used_parts,
659 BLOCK_LIST* completed_blocks,
660 TO_BLOCK_LIST* to_blocks);
664 ColPartition_LIST* block_parts,
665 ColPartition_LIST* used_parts);
671 ColPartition_LIST* block_parts,
672 ColPartition_LIST* used_parts);
687 #ifndef GRAPHICS_DISABLED
690 #endif // GRAPHICS_DISABLED
698 void SmoothPartnerRun(
int working_set_count);
715 const ColPartition* part1 = *static_cast<const ColPartition* const*>(p1);
716 const ColPartition* part2 = *static_cast<const ColPartition* const*>(p2);
717 int mid_y1 = part1->bounding_box_.
y_middle();
718 int mid_y2 = part2->bounding_box_.
y_middle();
719 if ((part2->bounding_box_.
bottom() <= mid_y1 &&
720 mid_y1 <= part2->bounding_box_.
top()) ||
721 (part1->bounding_box_.
bottom() <= mid_y2 &&
722 mid_y2 <= part1->bounding_box_.
top())) {
727 return mid_y2 - mid_y1;
732 first_column_ = column;
735 last_column_ = column;
741 enum SpacingNeighbourhood {
754 void RefinePartnersInternal(
bool upper,
bool get_desperate,
755 ColPartitionGrid* grid);
758 void RefinePartnersByType(
bool upper, ColPartition_CLIST* partners);
763 void RefinePartnerShortcuts(
bool upper, ColPartition_CLIST* partners);
770 void RefineTextPartnersByMerge(
bool upper,
bool desperate,
771 ColPartition_CLIST* partners,
772 ColPartitionGrid* grid);
774 void RefinePartnersByOverlap(
bool upper, ColPartition_CLIST* partners);
777 bool ThisPartitionBetter(
BLOBNBOX* bbox,
const ColPartition& other);
782 static void SmoothSpacings(
int resolution,
int page_height,
783 ColPartition_LIST* parts);
788 static bool OKSpacingBlip(
int resolution,
int median_spacing,
789 ColPartition** parts);
793 bool SpacingEqual(
int spacing,
int resolution)
const;
797 bool SpacingsEqual(
const ColPartition& other,
int resolution)
const;
802 bool SummedSpacingOK(
const ColPartition& other,
803 int spacing,
int resolution)
const;
807 int BottomSpacingMargin(
int resolution)
const;
811 int TopSpacingMargin(
int resolution)
const;
815 bool SizesSimilar(
const ColPartition& other)
const;
823 static void LeftEdgeRun(ColPartition_IT* part_it,
831 static void RightEdgeRun(ColPartition_IT* part_it,
838 int left_margin_ = 0;
840 int right_margin_ = 0;
844 int median_bottom_ = 0;
847 int median_height_ = 0;
849 int median_left_ = 0;
850 int median_right_ = 0;
852 int median_width_ = 0;
857 int good_blob_score_ = 0;
859 bool good_width_ =
false;
861 bool good_column_ =
false;
863 bool left_key_tab_ =
false;
865 bool right_key_tab_ =
false;
879 BLOBNBOX_CLIST boxes_;
881 ColPartition_CLIST upper_partners_;
883 ColPartition_CLIST lower_partners_;
885 WorkingPartSet* working_set_ =
nullptr;
887 ColPartitionSet* column_set_ =
nullptr;
889 bool last_add_was_vertical_ =
false;
892 bool block_owned_ =
false;
895 bool desperately_merged_ =
false;
896 bool owns_blobs_ =
true;
904 int first_column_ = -1;
905 int last_column_ = -1;
908 int top_spacing_ = 0;
909 int bottom_spacing_ = 0;
912 ColPartition* nearest_neighbor_above_ =
nullptr;
914 ColPartition* nearest_neighbor_below_ =
nullptr;
915 int space_above_ = 0;
916 int space_below_ = 0;
917 int space_to_left_ = 0;
918 int space_to_right_ = 0;
929 bool inside_table_column_ =
false;
939 #endif // TESSERACT_TEXTORD_COLPARTITION_H_