21 #ifndef TESSERACT_TEXTORD_BBGRID_H_ 22 #define TESSERACT_TEXTORD_BBGRID_H_ 24 #include <unordered_set> 29 #include "scrollview.h" 31 #include "allheaders.h" 44 ICOORD bleft,
int* left,
int* bottom);
47 ICOORD bleft,
int* left,
int* bottom);
49 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
class GridSearch;
80 void GridCoords(
int x,
int y,
int* grid_x,
int* grid_y)
const;
115 void Rotate(
const FCOORD& rotation);
119 IntGrid* NeighbourhoodSum()
const;
126 ASSERT_HOST(grid_x >= 0 && grid_x <
gridwidth());
127 ASSERT_HOST(grid_y >= 0 && grid_y <
gridheight());
132 bool RectMostlyOverThreshold(
const TBOX& rect,
int threshold)
const;
135 bool AnyZeroInRect(
const TBOX& rect)
const;
139 Pix* ThresholdToPix(
int threshold)
const;
159 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
class BBGrid 175 void ClearGridData(
void (*free_method)(BBC*));
182 void InsertBBox(
bool h_spread,
bool v_spread, BBC* bbox);
193 void InsertPixPtBBox(
int left,
int bottom, Pix* pix, BBC* bbox);
198 void RemoveBBox(BBC* bbox);
201 bool RectangleEmpty(
const TBOX& rect);
208 ScrollView* MakeWindow(
int x,
int y,
const char* window_name);
216 void AssertNoDuplicates();
219 virtual void HandleClick(
int x,
int y);
230 return reinterpret_cast<size_t>(ptr) /
sizeof(T);
236 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
class GridSearch {
239 : grid_(grid), unique_mode_(false),
240 previous_return_(nullptr), next_return_(nullptr) {
267 TBOX box = previous_return_->bounding_box();
268 int x_center = (box.
left()+box.
right())/2;
269 int y_center = (box.
top()+box.
bottom())/2;
271 grid_->GridCoords(x_center, y_center, &grid_x, &grid_y);
272 return (x_ == grid_x) && (y_ == grid_y);
292 void StartFullSearch();
294 BBC* NextFullSearch();
298 void StartRadSearch(
int x,
int y,
int max_radius);
301 BBC* NextRadSearch();
311 void StartSideSearch(
int x,
int ymin,
int ymax);
315 BBC* NextSideSearch(
bool right_to_left);
319 void StartVerticalSearch(
int xmin,
int xmax,
int y);
323 BBC* NextVerticalSearch(
bool top_to_bottom);
327 void StartRectSearch(
const TBOX& rect);
329 BBC* NextRectSearch();
335 void RepositionIterator();
339 void CommonStart(
int x,
int y);
375 const BBC* p1 = *
static_cast<const BBC* const*
>(void1);
376 const BBC* p2 = *
static_cast<const BBC* const*
>(void2);
377 int result = p1->bounding_box().left() - p2->bounding_box().left();
380 result = p1->bounding_box().right() - p2->bounding_box().right();
383 result = p1->bounding_box().bottom() - p2->bounding_box().bottom();
386 return p1->bounding_box().top() - p2->bounding_box().top();
393 const BBC* p1 = *
static_cast<const BBC* const*
>(void1);
394 const BBC* p2 = *
static_cast<const BBC* const*
>(void2);
395 int result = p2->bounding_box().right() - p1->bounding_box().right();
398 result = p2->bounding_box().left() - p1->bounding_box().left();
401 result = p1->bounding_box().bottom() - p2->bounding_box().bottom();
404 return p1->bounding_box().top() - p2->bounding_box().top();
411 const BBC* p1 = *
static_cast<const BBC* const*
>(void1);
412 const BBC* p2 = *
static_cast<const BBC* const*
>(void2);
413 int result = p1->bounding_box().bottom() - p2->bounding_box().bottom();
416 result = p1->bounding_box().top() - p2->bounding_box().top();
419 result = p1->bounding_box().left() - p2->bounding_box().left();
422 return p1->bounding_box().right() - p2->bounding_box().right();
428 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
432 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
434 int gridsize,
const ICOORD& bleft,
const ICOORD& tright)
436 Init(gridsize, bleft, tright);
439 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
446 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
450 GridBase::Init(gridsize, bleft, tright);
452 grid_ =
new BBC_CLIST[gridbuckets_];
456 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
458 for (
int i = 0; i < gridbuckets_; ++i) {
459 grid_[i].shallow_clear();
465 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
467 void (*free_method)(BBC*)) {
468 if (grid_ ==
nullptr)
return;
473 BBC_C_IT it(&bb_list);
475 it.add_after_then_move(bb);
477 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
478 free_method(it.data());
487 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
490 TBOX box = bbox->bounding_box();
491 int start_x, start_y, end_x, end_y;
492 GridCoords(box.
left(), box.
bottom(), &start_x, &start_y);
493 GridCoords(box.
right(), box.
top(), &end_x, &end_y);
498 int grid_index = start_y * gridwidth_;
499 for (
int y = start_y; y <= end_y; ++y, grid_index += gridwidth_) {
500 for (
int x = start_x; x <= end_x; ++x) {
501 grid_[grid_index + x].add_sorted(SortByBoxLeft<BBC>,
true, bbox);
515 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
517 Pix* pix, BBC* bbox) {
518 int width = pixGetWidth(pix);
519 int height = pixGetHeight(pix);
520 for (
int y = 0; y < height; ++y) {
521 l_uint32* data = pixGetData(pix) + y * pixGetWpl(pix);
522 for (
int x = 0; x < width; ++x) {
523 if (GET_DATA_BIT(data, x)) {
524 grid_[(bottom + y) * gridwidth_ + x + left].
525 add_sorted(SortByBoxLeft<BBC>,
true, bbox);
534 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
536 TBOX box = bbox->bounding_box();
537 int start_x, start_y, end_x, end_y;
538 GridCoords(box.
left(), box.
bottom(), &start_x, &start_y);
539 GridCoords(box.
right(), box.
top(), &end_x, &end_y);
540 int grid_index = start_y * gridwidth_;
541 for (
int y = start_y; y <= end_y; ++y, grid_index += gridwidth_) {
542 for (
int x = start_x; x <= end_x; ++x) {
543 BBC_C_IT it(&grid_[grid_index + x]);
544 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
545 if (it.data() == bbox)
553 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
562 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
565 for (
int y = 0; y < gridheight(); ++y) {
566 for (
int x = 0; x < gridwidth(); ++x) {
567 int cell_count = grid_[y * gridwidth() + x].length();
580 if (sv_event->
type == SVET_CLICK) {
581 grid_->HandleClick(sv_event->
x, sv_event->
y);
590 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
592 int x,
int y,
const char* window_name) {
594 #ifndef GRAPHICS_DISABLED 596 tright_.x() - bleft_.x(),
597 tright_.y() - bleft_.y(),
598 tright_.x() - bleft_.x(),
599 tright_.y() - bleft_.y(),
605 tab_win->
Rectangle(0, 0, tright_.x() - bleft_.x(), tright_.y() - bleft_.y());
614 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
616 #ifndef GRAPHICS_DISABLED 625 const TBOX& box = bbox->bounding_box();
626 int left_x = box.
left();
627 int right_x = box.
right();
628 int top_y = box.
top();
629 int bottom_y = box.
bottom();
631 tab_win->
Pen(box_color);
632 tab_win->
Rectangle(left_x, bottom_y, right_x, top_y);
639 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
642 for (
int i = gridwidth_ * gridheight_ - 1; i >= 0; --i) {
644 for (BBC_C_IT it(&grid_[i]); !it.at_last(); it.forward()) {
645 BBC* ptr = it.data();
648 for (it2.forward(); !it2.at_first(); it2.forward()) {
649 ASSERT_HOST(it2.data() != ptr);
656 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
658 tprintf(
"Click at (%d, %d)\n", x, y);
666 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
670 CommonStart(grid_->bleft_.x(), grid_->tright_.y());
676 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
681 while (it_.cycled_list()) {
683 if (x_ >= grid_->gridwidth_) {
692 TBOX box = previous_return_->bounding_box();
693 grid_->GridCoords(box.
left(), box.
bottom(), &x, &y);
694 }
while (x != x_ || y != y_);
695 return previous_return_;
699 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
705 max_radius_ = max_radius;
714 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
717 while (it_.cycled_list()) {
719 if (rad_index_ >= radius_) {
724 if (radius_ > max_radius_)
730 offset *= radius_ - rad_index_;
732 x_ = x_origin_ + offset.
x();
733 y_ = y_origin_ + offset.
y();
734 if (x_ >= 0 && x_ < grid_->gridwidth_ &&
735 y_ >= 0 && y_ < grid_->gridheight_)
739 }
while (unique_mode_ && returns_.find(previous_return_) != returns_.end());
741 returns_.insert(previous_return_);
742 return previous_return_;
747 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
749 int ymin,
int ymax) {
754 radius_ = ((ymax - ymin) * 2 + grid_->gridsize_ - 1) / grid_->gridsize_;
756 CommonStart(x, ymax);
762 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
765 while (it_.cycled_list()) {
767 if (rad_index_ > radius_) {
773 if (x_ < 0 || x_ >= grid_->gridwidth_)
776 y_ = y_origin_ - rad_index_;
777 if (y_ >= 0 && y_ < grid_->gridheight_)
781 }
while (unique_mode_ && returns_.find(previous_return_) != returns_.end());
783 returns_.insert(previous_return_);
784 return previous_return_;
789 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
795 radius_ = (xmax - xmin + grid_->gridsize_ - 1) / grid_->gridsize_;
797 CommonStart(xmin, y);
803 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
805 bool top_to_bottom) {
807 while (it_.cycled_list()) {
809 if (rad_index_ > radius_) {
815 if (y_ < 0 || y_ >= grid_->gridheight_)
818 x_ = x_origin_ + rad_index_;
819 if (x_ >= 0 && x_ < grid_->gridwidth_)
823 }
while (unique_mode_ && returns_.find(previous_return_) != returns_.end());
825 returns_.insert(previous_return_);
826 return previous_return_;
831 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
837 CommonStart(rect.
left(), rect.
top());
839 &max_radius_, &y_origin_);
843 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
846 while (it_.cycled_list()) {
848 if (x_ > max_radius_) {
857 }
while (!rect_.overlap(previous_return_->bounding_box()) ||
858 (unique_mode_ && returns_.find(previous_return_) != returns_.end()));
860 returns_.insert(previous_return_);
861 return previous_return_;
867 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
869 if (previous_return_ !=
nullptr) {
873 BBC* prev_data =
nullptr;
874 BBC* new_previous_return =
nullptr;
876 for (it_.mark_cycle_pt(); !it_.cycled_list();) {
877 if (it_.data() == previous_return_) {
878 new_previous_return = prev_data;
881 next_return_ = it_.cycled_list() ? nullptr : it_.data();
883 prev_data = it_.data();
888 previous_return_ = new_previous_return;
889 RepositionIterator();
893 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
905 if (!it_.empty() && it_.data() == next_return_) {
909 for (it_.mark_cycle_pt(); !it_.cycled_list(); it_.forward()) {
910 if (it_.data() == previous_return_ ||
911 it_.data_relative(1) == next_return_) {
917 previous_return_ =
nullptr;
918 next_return_ =
nullptr;
922 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
924 grid_->GridCoords(x, y, &x_origin_, &y_origin_);
928 previous_return_ =
nullptr;
929 next_return_ = it_.empty() ? nullptr : it_.data();
934 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
936 previous_return_ = it_.data();
938 next_return_ = it_.cycled_list() ? nullptr : it_.data();
939 return previous_return_;
943 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
945 previous_return_ =
nullptr;
946 next_return_ =
nullptr;
952 template<
class BBC,
class BBC_CLIST,
class BBC_C_IT>
954 it_= &(grid_->grid_[y_ * grid_->gridwidth_ + x_]);
960 #endif // TESSERACT_TEXTORD_BBGRID_H_ int radius_
Definition: bbgrid.h:356
static ICOORD chain_step(int chaindir)
Definition: coutln.cpp:1050
ICOORD bleft_
Definition: bbgrid.h:91
ICOORD tright_
Definition: bbgrid.h:92
void Notify(const SVEvent *sv_event)
Definition: bbgrid.h:579
int x_
Definition: bbgrid.h:360
Definition: scrollview.h:61
GridSearch(BBGrid< BBC, BBC_CLIST, BBC_C_IT > *grid)
Definition: bbgrid.h:238
int16_t right() const
Definition: rect.h:79
TabEventHandler(G *grid)
Definition: bbgrid.h:577
int16_t x() const
access function
Definition: points.h:53
void StartFullSearch()
Definition: bbgrid.h:667
G * grid_
Definition: bbgrid.h:585
SVEventType type
Definition: scrollview.h:64
int gridsize_
Definition: bbgrid.h:87
int SortByBoxBottom(const void *void1, const void *void2)
Definition: bbgrid.h:409
Pix * TraceBlockOnReducedPix(BLOCK *block, int gridsize, ICOORD bleft, int *left, int *bottom)
Definition: bbgrid.cpp:255
Pix * TraceOutlineOnReducedPix(C_OUTLINE *outline, int gridsize, ICOORD bleft, int *left, int *bottom)
Definition: bbgrid.cpp:229
int gridheight_
Definition: bbgrid.h:89
int SortByBoxLeft(const void *void1, const void *void2)
Definition: bbgrid.h:373
BBGrid()
Definition: bbgrid.h:429
bool ReturnedSeedElement() const
Definition: bbgrid.h:266
int x
Definition: scrollview.h:66
int gridwidth() const
Definition: bbgrid.h:67
Definition: baseapi.cpp:94
void ClipGridCoords(int *x, int *y) const
Definition: bbgrid.cpp:60
int16_t bottom() const
Definition: rect.h:65
int GridCellValue(int grid_x, int grid_y) const
Definition: bbgrid.h:121
int GridX() const
Definition: bbgrid.h:244
int * grid_
Definition: bbgrid.h:142
int rad_index_
Definition: bbgrid.h:357
int gridwidth_
Definition: bbgrid.h:88
int rad_dir_
Definition: bbgrid.h:358
Definition: ocrblock.h:30
TBOX rect_
Definition: bbgrid.h:359
const ICOORD & bleft() const
Definition: bbgrid.h:73
int gridsize() const
Definition: bbgrid.h:64
int16_t y() const
access_function
Definition: points.h:57
void Init(int gridsize, const ICOORD &bleft, const ICOORD &tright)
Definition: bbgrid.cpp:41
BBC * NextRectSearch()
Definition: bbgrid.h:844
BBGrid< BBC, BBC_CLIST, BBC_C_IT > * grid_
Definition: bbgrid.h:350
size_t operator()(const T *ptr) const
Definition: bbgrid.h:229
int gridheight() const
Definition: bbgrid.h:70
void StartRectSearch(const TBOX &rect)
Definition: bbgrid.h:832
void SetUniqueMode(bool mode)
Definition: bbgrid.h:255
void GridCoords(int x, int y, int *grid_x, int *grid_y) const
Definition: bbgrid.cpp:53
int max_radius_
Definition: bbgrid.h:355
integer coordinate
Definition: points.h:32
int16_t top() const
Definition: rect.h:58
void RemoveBBox()
Definition: bbgrid.h:868
BBC_CLIST * grid_
Definition: bbgrid.h:222
int x_origin_
Definition: bbgrid.h:353
int y_origin_
Definition: bbgrid.h:354
BBC * previous_return_
Definition: bbgrid.h:363
std::unordered_set< BBC *, PtrHash< BBC > > returns_
Definition: bbgrid.h:368
int16_t left() const
Definition: rect.h:72
int GridY() const
Definition: bbgrid.h:247
Definition: scrollview.h:86
int SortRightToLeft(const void *void1, const void *void2)
Definition: bbgrid.h:391
int y_
Definition: bbgrid.h:361
const ICOORD & tright() const
Definition: bbgrid.h:76
bool unique_mode_
Definition: bbgrid.h:362
BBC_C_IT it_
Definition: bbgrid.h:366
int gridbuckets_
Definition: bbgrid.h:90
BBC * NextFullSearch()
Definition: bbgrid.h:677
BBC * next_return_
Definition: bbgrid.h:364
void SetGridCell(int grid_x, int grid_y, int value)
Definition: bbgrid.h:125
int y
Definition: scrollview.h:67