00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020
00021 #ifndef TESSERACT_TEXTORD_BBGRID_H__
00022 #define TESSERACT_TEXTORD_BBGRID_H__
00023
00024 #include "clst.h"
00025 #include "coutln.h"
00026 #include "rect.h"
00027 #include "scrollview.h"
00028
00029
00030
00031 #ifdef HAVE_CONFIG_H
00032 #include "config_auto.h"
00033 #endif
00034 #ifdef HAVE_LIBLEPT
00035 #include "allheaders.h"
00036 #endif
00037
00038 class BLOCK;
00039
00040 namespace tesseract {
00041
00042 #ifdef HAVE_LIBLEPT
00043
00044
00045
00046
00047
00048
00049 Pix* TraceOutlineOnReducedPix(C_OUTLINE* outline, int gridsize,
00050 ICOORD bleft, int* left, int* bottom);
00051
00052 Pix* TraceBlockOnReducedPix(BLOCK* block, int gridsize,
00053 ICOORD bleft, int* left, int* bottom);
00054 #endif
00055
00056 template<class BBC, class BBC_CLIST, class BBC_C_IT> class GridSearch;
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 template<class BBC, class BBC_CLIST, class BBC_C_IT> class BBGrid {
00073 friend class GridSearch<BBC, BBC_CLIST, BBC_C_IT>;
00074 public:
00075 BBGrid();
00076 BBGrid(int gridsize, const ICOORD& bleft, const ICOORD& tright);
00077 virtual ~BBGrid();
00078
00079
00080
00081 void Init(int gridsize, const ICOORD& bleft, const ICOORD& tright);
00082
00083
00084 void Clear();
00085
00086
00087 void ClearGridData(void (*free_method)(BBC*));
00088
00089
00090 int gridsize() const {
00091 return gridsize_;
00092 }
00093 int gridwidth() const {
00094 return gridwidth_;
00095 }
00096 int gridheight() const {
00097 return gridheight_;
00098 }
00099 ICOORD bleft() const {
00100 return bleft_;
00101 }
00102 ICOORD tright() const {
00103 return tright_;
00104 }
00105
00106
00107
00108
00109
00110
00111 void InsertBBox(bool h_spread, bool v_spread, BBC* bbox);
00112 #ifdef HAVE_LIBLEPT
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 void InsertPixPtBBox(int left, int bottom, Pix* pix, BBC* bbox);
00123 #endif
00124
00125
00126
00127 void RemoveBBox(BBC* bbox);
00128
00129
00130 void GridCoords(int x, int y, int* grid_x, int* grid_y);
00131
00132
00133 void ClipGridCoords(int* x, int* y);
00134
00135
00136 ScrollView* MakeWindow(int x, int y, const char* window_name);
00137
00138
00139
00140
00141 void DisplayBoxes(ScrollView* window);
00142
00143
00144 void AssertNoDuplicates();
00145
00146
00147 virtual void HandleClick(int x, int y);
00148
00149 protected:
00150 int gridsize_;
00151 int gridwidth_;
00152 int gridheight_;
00153 int gridbuckets_;
00154 ICOORD bleft_;
00155 ICOORD tright_;
00156 BBC_CLIST* grid_;
00157
00158 private:
00159 };
00160
00161
00162 template<class BBC, class BBC_CLIST, class BBC_C_IT> class GridSearch {
00163 public:
00164 GridSearch(BBGrid<BBC, BBC_CLIST, BBC_C_IT>* grid)
00165 : grid_(grid), previous_return_(NULL), next_return_(NULL) {
00166 }
00167
00168
00169 int GridX() const {
00170 return x_;
00171 }
00172 int GridY() const {
00173 return y_;
00174 }
00175
00176
00177
00178
00179
00180
00181 bool ReturnedSeedElement() const {
00182 TBOX box = previous_return_->bounding_box();
00183 int x_center = (box.left()+box.right())/2;
00184 int y_center = (box.top()+box.bottom())/2;
00185 int grid_x, grid_y;
00186 grid_->GridCoords(x_center, y_center, &grid_x, &grid_y);
00187 return (x_ == grid_x) && (y_ == grid_y);
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 void StartFullSearch();
00205
00206 BBC* NextFullSearch();
00207
00208
00209
00210 void StartRadSearch(int x, int y, int max_radius);
00211
00212
00213 BBC* NextRadSearch();
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 void StartSideSearch(int x, int ymin, int ymax);
00224
00225
00226
00227 BBC* NextSideSearch(bool right_to_left);
00228
00229
00230
00231 void StartVerticalSearch(int xmin, int xmax, int y);
00232
00233
00234
00235 BBC* NextVerticalSearch(bool top_to_bottom);
00236
00237
00238
00239 void StartRectSearch(const TBOX& rect);
00240
00241 BBC* NextRectSearch();
00242
00243
00244
00245
00246 void RemoveBBox();
00247 void RepositionIterator();
00248
00249 private:
00250
00251 void CommonStart(int x, int y);
00252
00253 BBC* CommonNext();
00254
00255 BBC* CommonEnd();
00256
00257
00258 void SetIterator();
00259
00260 private:
00261
00262 BBGrid<BBC, BBC_CLIST, BBC_C_IT>* grid_;
00263
00264
00265 int x_origin_;
00266 int y_origin_;
00267 int max_radius_;
00268 int radius_;
00269 int rad_index_;
00270 int rad_dir_;
00271 TBOX rect_;
00272 int x_;
00273 int y_;
00274 BBC* previous_return_;
00275 BBC* next_return_;
00276
00277 BBC_C_IT it_;
00278 };
00279
00280
00281 template<class BBC>
00282 int SortByBoxLeft(const void* void1, const void* void2) {
00283
00284 const BBC* p1 = *reinterpret_cast<const BBC* const *>(void1);
00285 const BBC* p2 = *reinterpret_cast<const BBC* const *>(void2);
00286 return p1->bounding_box().left() - p2->bounding_box().left();
00287 }
00288
00290
00292 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00293 BBGrid<BBC, BBC_CLIST, BBC_C_IT>::BBGrid() : grid_(NULL) {
00294 }
00295
00296 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00297 BBGrid<BBC, BBC_CLIST, BBC_C_IT>::BBGrid(
00298 int gridsize, const ICOORD& bleft, const ICOORD& tright)
00299 : grid_(NULL) {
00300 Init(gridsize, bleft, tright);
00301 }
00302
00303 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00304 BBGrid<BBC, BBC_CLIST, BBC_C_IT>::~BBGrid() {
00305 if (grid_ != NULL)
00306 delete [] grid_;
00307 }
00308
00309
00310
00311 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00312 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::Init(int gridsize,
00313 const ICOORD& bleft,
00314 const ICOORD& tright) {
00315 gridsize_ = gridsize;
00316 bleft_ = bleft;
00317 tright_ = tright;
00318 if (grid_ != NULL)
00319 delete [] grid_;
00320 if (gridsize_ == 0)
00321 gridsize_ = 1;
00322 gridwidth_ = (tright.x() - bleft.x() + gridsize_ - 1) / gridsize_;
00323 gridheight_ = (tright.y() - bleft.y() + gridsize_ - 1) / gridsize_;
00324 gridbuckets_ = gridwidth_ * gridheight_;
00325 grid_ = new BBC_CLIST[gridbuckets_];
00326 }
00327
00328
00329 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00330 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::Clear() {
00331 for (int i = 0; i < gridbuckets_; ++i) {
00332 grid_[i].shallow_clear();
00333 }
00334 }
00335
00336
00337
00338 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00339 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::ClearGridData(
00340 void (*free_method)(BBC*)) {
00341 if (grid_ == NULL) return;
00342 GridSearch<BBC, BBC_CLIST, BBC_C_IT> search(this);
00343 search.StartFullSearch();
00344 BBC* bb;
00345 BBC_CLIST bb_list;
00346 BBC_C_IT it(&bb_list);
00347 while ((bb = search.NextFullSearch()) != NULL) {
00348 it.add_after_then_move(bb);
00349 }
00350 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
00351 free_method(it.data());
00352 }
00353 }
00354
00355
00356
00357
00358
00359
00360 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00361 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::InsertBBox(bool h_spread, bool v_spread,
00362 BBC* bbox) {
00363 TBOX box = bbox->bounding_box();
00364 int start_x, start_y, end_x, end_y;
00365 GridCoords(box.left(), box.bottom(), &start_x, &start_y);
00366 GridCoords(box.right(), box.top(), &end_x, &end_y);
00367 if (!h_spread)
00368 end_x = start_x;
00369 if (!v_spread)
00370 end_y = start_y;
00371 int grid_index = start_y * gridwidth_;
00372 for (int y = start_y; y <= end_y; ++y, grid_index += gridwidth_) {
00373 for (int x = start_x; x <= end_x; ++x) {
00374 grid_[grid_index + x].add_sorted(SortByBoxLeft<BBC>, true, bbox);
00375 }
00376 }
00377 }
00378
00379 #ifdef HAVE_LIBLEPT
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00390 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::InsertPixPtBBox(int left, int bottom,
00391 Pix* pix, BBC* bbox) {
00392 int width = pixGetWidth(pix);
00393 int height = pixGetHeight(pix);
00394 for (int y = 0; y < height; ++y) {
00395 l_uint32* data = pixGetData(pix) + y * pixGetWpl(pix);
00396 for (int x = 0; x < width; ++x) {
00397 if (GET_DATA_BIT(data, x)) {
00398 grid_[(bottom + y) * gridwidth_ + x + left].
00399 add_sorted(SortByBoxLeft<BBC>, true, bbox);
00400 }
00401 }
00402 }
00403 }
00404 #endif
00405
00406
00407
00408
00409 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00410 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::RemoveBBox(BBC* bbox) {
00411 TBOX box = bbox->bounding_box();
00412 int start_x, start_y, end_x, end_y;
00413 GridCoords(box.left(), box.bottom(), &start_x, &start_y);
00414 GridCoords(box.right(), box.top(), &end_x, &end_y);
00415 int grid_index = start_y * gridwidth_;
00416 for (int y = start_y; y <= end_y; ++y, grid_index += gridwidth_) {
00417 for (int x = start_x; x <= end_x; ++x) {
00418 BBC_C_IT it(&grid_[grid_index + x]);
00419 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
00420 if (it.data() == bbox)
00421 it.extract();
00422 }
00423 }
00424 }
00425 }
00426
00427
00428 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00429 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::GridCoords(int x, int y,
00430 int* grid_x, int* grid_y) {
00431 *grid_x = (x - bleft_.x()) / gridsize_;
00432 *grid_y = (y - bleft_.y()) / gridsize_;
00433 ClipGridCoords(grid_x, grid_y);
00434 }
00435
00436
00437 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00438 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::ClipGridCoords(int* x, int* y) {
00439 if (*x < 0) *x = 0;
00440 if (*x >= gridwidth_) *x = gridwidth_ - 1;
00441 if (*y < 0) *y = 0;
00442 if (*y >= gridheight_) *y = gridheight_ - 1;
00443 }
00444
00445 template<class G> class TabEventHandler : public SVEventHandler {
00446 public:
00447 explicit TabEventHandler(G* grid) : grid_(grid) {
00448 }
00449 void Notify(const SVEvent* sv_event) {
00450 if (sv_event->type == SVET_CLICK) {
00451 grid_->HandleClick(sv_event->x, sv_event->y);
00452 }
00453 }
00454 private:
00455 G* grid_;
00456 };
00457
00458
00459
00460 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00461 ScrollView* BBGrid<BBC, BBC_CLIST, BBC_C_IT>::MakeWindow(
00462 int x, int y, const char* window_name) {
00463 ScrollView* tab_win = NULL;
00464 #ifndef GRAPHICS_DISABLED
00465 tab_win = new ScrollView(window_name, x, y,
00466 tright_.x() - bleft_.x(),
00467 tright_.y() - bleft_.y(),
00468 tright_.x() - bleft_.x(),
00469 tright_.y() - bleft_.y(),
00470 true);
00471 TabEventHandler<BBGrid<BBC, BBC_CLIST, BBC_C_IT> >* handler =
00472 new TabEventHandler<BBGrid<BBC, BBC_CLIST, BBC_C_IT> >(this);
00473 tab_win->AddEventHandler(handler);
00474 tab_win->Pen(ScrollView::GREY);
00475 tab_win->Rectangle(0, 0, tright_.x(), tright_.y());
00476 #endif
00477 return tab_win;
00478 }
00479
00480
00481
00482
00483
00484 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00485 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::DisplayBoxes(ScrollView* tab_win) {
00486 #ifndef GRAPHICS_DISABLED
00487 tab_win->Pen(ScrollView::BLUE);
00488 tab_win->Brush(ScrollView::NONE);
00489
00490
00491 GridSearch<BBC, BBC_CLIST, BBC_C_IT> gsearch(this);
00492 gsearch.StartFullSearch();
00493 BBC* bbox;
00494 while ((bbox = gsearch.NextFullSearch()) != NULL) {
00495 TBOX box = bbox->bounding_box();
00496 int left_x = box.left();
00497 int right_x = box.right();
00498 int top_y = box.top();
00499 int bottom_y = box.bottom();
00500 ScrollView::Color box_color = bbox->BoxColor();
00501 tab_win->Pen(box_color);
00502 tab_win->Rectangle(left_x, bottom_y, right_x, top_y);
00503 }
00504 tab_win->Update();
00505 #endif
00506 }
00507
00508
00509 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00510 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::AssertNoDuplicates() {
00511
00512 for (int i = gridwidth_ * gridheight_ - 1; i >= 0; --i) {
00513
00514 for (BBC_C_IT it(&grid_[i]); !it.at_last(); it.forward()) {
00515 BBC* ptr = it.data();
00516 BBC_C_IT it2(it);
00517
00518 for (it2.forward(); !it2.at_first(); it2.forward()) {
00519 ASSERT_HOST(it2.data() != ptr);
00520 }
00521 }
00522 }
00523 }
00524
00525
00526 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00527 void BBGrid<BBC, BBC_CLIST, BBC_C_IT>::HandleClick(int x, int y) {
00528 tprintf("Click at (%d, %d)\n", x, y);
00529 }
00530
00532
00534
00535
00536 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00537 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::StartFullSearch() {
00538
00539
00540 CommonStart(grid_->bleft_.x(), grid_->tright_.y());
00541 }
00542
00543
00544
00545
00546 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00547 BBC* GridSearch<BBC, BBC_CLIST, BBC_C_IT>::NextFullSearch() {
00548 int x;
00549 int y;
00550 do {
00551 while (it_.cycled_list()) {
00552 ++x_;
00553 if (x_ >= grid_->gridwidth_) {
00554 --y_;
00555 if (y_ < 0)
00556 return CommonEnd();
00557 x_ = 0;
00558 }
00559 SetIterator();
00560 }
00561 CommonNext();
00562 TBOX box = previous_return_->bounding_box();
00563 grid_->GridCoords(box.left(), box.bottom(), &x, &y);
00564 } while (x != x_ || y != y_);
00565 return previous_return_;
00566 }
00567
00568
00569 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00570 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::StartRadSearch(int x, int y,
00571 int max_radius) {
00572
00573
00574
00575 max_radius_ = max_radius;
00576 radius_ = 0;
00577 rad_index_ = 0;
00578 rad_dir_ = 3;
00579 CommonStart(x, y);
00580 }
00581
00582
00583
00584 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00585 BBC* GridSearch<BBC, BBC_CLIST, BBC_C_IT>::NextRadSearch() {
00586 while (it_.cycled_list()) {
00587 ++rad_index_;
00588 if (rad_index_ >= radius_) {
00589 ++rad_dir_;
00590 rad_index_ = 0;
00591 if (rad_dir_ >= 4) {
00592 ++radius_;
00593 if (radius_ > max_radius_)
00594 return CommonEnd();
00595 rad_dir_ = 0;
00596 }
00597 }
00598 ICOORD offset = C_OUTLINE::chain_step(rad_dir_);
00599 offset *= radius_ - rad_index_;
00600 offset += C_OUTLINE::chain_step(rad_dir_ + 1) * rad_index_;
00601 x_ = x_origin_ + offset.x();
00602 y_ = y_origin_ + offset.y();
00603 if (x_ >= 0 && x_ < grid_->gridwidth_ &&
00604 y_ >= 0 && y_ < grid_->gridheight_)
00605 SetIterator();
00606 }
00607 return CommonNext();
00608 }
00609
00610
00611
00612 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00613 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::StartSideSearch(int x,
00614 int ymin, int ymax) {
00615
00616
00617
00618
00619 radius_ = ((ymax - ymin) * 2 + grid_->gridsize_ - 1) / grid_->gridsize_;
00620 rad_index_ = 0;
00621 CommonStart(x, ymax);
00622 }
00623
00624
00625
00626
00627 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00628 BBC* GridSearch<BBC, BBC_CLIST, BBC_C_IT>::NextSideSearch(bool right_to_left) {
00629 while (it_.cycled_list()) {
00630 ++rad_index_;
00631 if (rad_index_ > radius_) {
00632 if (right_to_left)
00633 --x_;
00634 else
00635 ++x_;
00636 rad_index_ = 0;
00637 if (x_ < 0 || x_ >= grid_->gridwidth_)
00638 return CommonEnd();
00639 }
00640 y_ = y_origin_ - rad_index_;
00641 if (y_ >= 0 && y_ < grid_->gridheight_)
00642 SetIterator();
00643 }
00644 return CommonNext();
00645 }
00646
00647
00648
00649 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00650 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::StartVerticalSearch(int xmin,
00651 int xmax,
00652 int y) {
00653
00654
00655 radius_ = (xmax - xmin + grid_->gridsize_ - 1) / grid_->gridsize_;
00656 rad_index_ = 0;
00657 CommonStart(xmin, y);
00658 }
00659
00660
00661
00662
00663 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00664 BBC* GridSearch<BBC, BBC_CLIST, BBC_C_IT>::NextVerticalSearch(
00665 bool top_to_bottom) {
00666 while (it_.cycled_list()) {
00667 ++rad_index_;
00668 if (rad_index_ > radius_) {
00669 if (top_to_bottom)
00670 --y_;
00671 else
00672 ++y_;
00673 rad_index_ = 0;
00674 if (y_ < 0 || y_ >= grid_->gridheight_)
00675 return CommonEnd();
00676 }
00677 x_ = x_origin_ + rad_index_;
00678 if (x_ >= 0 && x_ < grid_->gridwidth_)
00679 SetIterator();
00680 }
00681 return CommonNext();
00682 }
00683
00684
00685
00686 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00687 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::StartRectSearch(const TBOX& rect) {
00688
00689
00690
00691 rect_ = rect;
00692 CommonStart(rect.left(), rect.top());
00693 grid_->GridCoords(rect.right(), rect.bottom(),
00694 &max_radius_, &y_origin_);
00695 }
00696
00697
00698 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00699 BBC* GridSearch<BBC, BBC_CLIST, BBC_C_IT>::NextRectSearch() {
00700 while (it_.cycled_list()) {
00701 ++x_;
00702 if (x_ > max_radius_) {
00703 --y_;
00704 x_ = x_origin_;
00705 if (y_ < y_origin_)
00706 return CommonEnd();
00707 }
00708 SetIterator();
00709 }
00710 return CommonNext();
00711 }
00712
00713
00714
00715
00716 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00717 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::RemoveBBox() {
00718 if (previous_return_ != NULL) {
00719
00720
00721
00722 BBC* prev_data = NULL;
00723 BBC* new_previous_return = NULL;
00724 it_.move_to_first();
00725 for (it_.mark_cycle_pt(); !it_.cycled_list();) {
00726 if (it_.data() == previous_return_) {
00727 new_previous_return = prev_data;
00728 it_.extract();
00729 it_.forward();
00730 next_return_ = it_.cycled_list() ? NULL : it_.data();
00731 } else {
00732 prev_data = it_.data();
00733 it_.forward();
00734 }
00735 }
00736 grid_->RemoveBBox(previous_return_);
00737 previous_return_ = new_previous_return;
00738 RepositionIterator();
00739 }
00740 }
00741
00742 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00743 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::RepositionIterator() {
00744
00745
00746
00747 it_.move_to_first();
00748 for (it_.mark_cycle_pt(); !it_.cycled_list(); it_.forward()) {
00749 if (it_.data() == previous_return_ ||
00750 it_.data_relative(1) == next_return_) {
00751 CommonNext();
00752 return;
00753 }
00754 }
00755
00756 previous_return_ = NULL;
00757 next_return_ = NULL;
00758 }
00759
00760
00761 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00762 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::CommonStart(int x, int y) {
00763 grid_->GridCoords(x, y, &x_origin_, &y_origin_);
00764 x_ = x_origin_;
00765 y_ = y_origin_;
00766 SetIterator();
00767 previous_return_ = NULL;
00768 next_return_ = it_.empty() ? NULL : it_.data();
00769 }
00770
00771
00772 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00773 BBC* GridSearch<BBC, BBC_CLIST, BBC_C_IT>::CommonNext() {
00774 previous_return_ = it_.data();
00775 it_.forward();
00776 next_return_ = it_.cycled_list() ? NULL : it_.data();
00777 return previous_return_;
00778 }
00779
00780
00781 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00782 BBC* GridSearch<BBC, BBC_CLIST, BBC_C_IT>::CommonEnd() {
00783 previous_return_ = NULL;
00784 next_return_ = NULL;
00785 return NULL;
00786 }
00787
00788
00789
00790 template<class BBC, class BBC_CLIST, class BBC_C_IT>
00791 void GridSearch<BBC, BBC_CLIST, BBC_C_IT>::SetIterator() {
00792 it_= &(grid_->grid_[y_ * grid_->gridwidth_ + x_]);
00793 it_.mark_cycle_pt();
00794 }
00795
00796 }
00797
00798 #endif // TESSERACT_TEXTORD_BBGRID_H__