src/ccstruct/pageres.cpp
WERD_RES *PAGE_RES_IT::internal_forward(bool new_block, bool empty_ok) {
  bool new_row = false;

  prev_block_res = block_res;
  prev_row_res = row_res;
  prev_word_res = word_res;
  block_res = next_block_res;
  row_res = next_row_res;
  word_res = next_word_res;
  wr_it_of_current_word = wr_it_of_next_word;
  next_block_res = nullptr;
  next_row_res = nullptr;
  next_word_res = nullptr;

  while (!block_res_it.cycled_list()) {
    if (new_block) {
      new_block = false;
      row_res_it.set_to_list(&block_res_it.data()->row_res_list);
      row_res_it.mark_cycle_pt();
      if (row_res_it.empty() && empty_ok) {
        next_block_res = block_res_it.data();
        break;
      }
      new_row = true;
    }
    while (!row_res_it.cycled_list()) {
      if (new_row) {
        new_row = false;
        word_res_it.set_to_list(&row_res_it.data()->word_res_list);
        word_res_it.mark_cycle_pt();
      }
      // Skip any part_of_combo words.
      while (!word_res_it.cycled_list() && word_res_it.data()->part_of_combo) {
        word_res_it.forward();
      }
      if (!word_res_it.cycled_list()) {
        next_block_res = block_res_it.data();
        next_row_res = row_res_it.data();
        next_word_res = word_res_it.data();
        wr_it_of_next_word = word_res_it;
        word_res_it.forward();
        goto foundword;
      }
      // end of row reached
      row_res_it.forward();
      new_row = true;
    }
    // end of block reached
    block_res_it.forward();
    new_block = true;
  }
foundword:
  // Update prev_word_best_choice pointer.
  if (page_res != nullptr && page_res->prev_word_best_choice != nullptr) {
    *page_res->prev_word_best_choice = (new_block || prev_word_res == nullptr)
                                           ? nullptr
                                           : prev_word_res->best_choice;
  }
  return word_res;
}
/*************************************************************************
 * PAGE_RES_IT::internal_forward
 *
 * Find the next word on the page. If empty_ok is true, then non-text blocks
 * and text blocks with no text are visited as if they contain a single
 * imaginary word in a single imaginary row. (word() and row() both return
 *nullptr in such a block and the return value is nullptr.) If empty_ok is
 *false, the old behaviour is maintained. Each real word is visited and empty
 *and non-text blocks and rows are skipped. new_block is used to initialize the
 *iterators for a new block. The iterator maintains pointers to block, row and
 *word for the previous, current and next words.  These are correct, regardless
 *of block/row boundaries. nullptr values denote start and end of the page.
 *************************************************************************/
:internal_forward
Find the next word on the page. If empty_ok is true, then non-text blocks
and text blocks with no text are visited as if they contain a single
imaginary word in a single imaginary row. (word() and row() both return
nullptr in such a block and the return value is nullptr.) If empty_ok is
false, the old behaviour is maintained. Each real word is visited and empty
and non-text blocks and rows are skipped. new_block is used to initialize the
iterators for a new block. The iterator maintains pointers to block, row and
word for the previous, current and next words.  These are correct, regardless
of block/row boundaries. nullptr values denote start and end of the page.
: internal_forward Find the next word on the page . If empty_ok is true then non - text blocks and text blocks with no text are visited as if they contain a single imaginary word in a single imaginary row . ( word () and row () both return nullptr in such a block and the return value is nullptr . ) If empty_ok is false the old behaviour is maintained . Each real word is visited and empty and non - text blocks and rows are skipped . new_block is used to initialize the iterators for a new block . The iterator maintains pointers to block row and word for the previous current and next words . These are correct regardless of block / row boundaries . nullptr values denote start and end of the page .
WERD_RES *PAGE_RES_IT::internal_forward(bool new_block, bool empty_ok) {
  bool new_row = false;
  prev_block_res = block_res;
  prev_row_res = row_res;
  prev_word_res = word_res;
  block_res = next_block_res;
  row_res = next_row_res;
  word_res = next_word_res;
  wr_it_of_current_word = wr_it_of_next_word;
  next_block_res = nullptr;
  next_row_res = nullptr;
  next_word_res = nullptr;
  while (!block_res_it.cycled_list()) {
    if (new_block) {
      new_block = false;
      row_res_it.set_to_list(&block_res_it.data()->row_res_list);
      row_res_it.mark_cycle_pt();
      if (row_res_it.empty() && empty_ok) {
        next_block_res = block_res_it.data();
        break;
      }
      new_row = true;
    }
    while (!row_res_it.cycled_list()) {
      if (new_row) {
        new_row = false;
        word_res_it.set_to_list(&row_res_it.data()->word_res_list);
        word_res_it.mark_cycle_pt();
      }
      while (!word_res_it.cycled_list() && word_res_it.data()->part_of_combo) {
        word_res_it.forward();
      }
      if (!word_res_it.cycled_list()) {
        next_block_res = block_res_it.data();
        next_row_res = row_res_it.data();
        next_word_res = word_res_it.data();
        wr_it_of_next_word = word_res_it;
        word_res_it.forward();
        goto foundword;
      }
      row_res_it.forward();
      new_row = true;
    }
    block_res_it.forward();
    new_block = true;
  }
foundword:
  if (page_res != nullptr && page_res->prev_word_best_choice != nullptr) {
    *page_res->prev_word_best_choice = (new_block || prev_word_res == nullptr)
                                           ? nullptr
                                           : prev_word_res->best_choice;
  }
  return word_res;
}
WERD_RES * PAGE_RES_IT :: internal_forward ( bool new_block , bool empty_ok ) { bool new_row = false ; prev_block_res = block_res ; prev_row_res = row_res ; prev_word_res = word_res ; block_res = next_block_res ; row_res = next_row_res ; word_res = next_word_res ; wr_it_of_current_word = wr_it_of_next_word ; next_block_res = nullptr ; next_row_res = nullptr ; next_word_res = nullptr ; while ( ! block_res_it . cycled_list ( ) ) { if ( new_block ) { new_block = false ; row_res_it . set_to_list ( & block_res_it . data ( ) -> row_res_list ) ; row_res_it . mark_cycle_pt ( ) ; if ( row_res_it . empty ( ) && empty_ok ) { next_block_res = block_res_it . data ( ) ; break ; } new_row = true ; } while ( ! row_res_it . cycled_list ( ) ) { if ( new_row ) { new_row = false ; word_res_it . set_to_list ( & row_res_it . data ( ) -> word_res_list ) ; word_res_it . mark_cycle_pt ( ) ; } while ( ! word_res_it . cycled_list ( ) && word_res_it . data ( ) -> part_of_combo ) { word_res_it . forward ( ) ; } if ( ! word_res_it . cycled_list ( ) ) { next_block_res = block_res_it . data ( ) ; next_row_res = row_res_it . data ( ) ; next_word_res = word_res_it . data ( ) ; wr_it_of_next_word = word_res_it ; word_res_it . forward ( ) ; goto foundword ; } row_res_it . forward ( ) ; new_row = true ; } block_res_it . forward ( ) ; new_block = true ; } foundword : if ( page_res != nullptr && page_res -> prev_word_best_choice != nullptr ) { * page_res -> prev_word_best_choice = ( new_block || prev_word_res == nullptr ) ? nullptr : prev_word_res -> best_choice ; } return word_res ; }
PAGE_RES_IT::internal_forward
 Find the next word on the page.
PAGE_RES_IT :: internal_forward Find the next word on the page .
// Skip any part_of_combo words. // end of row reached // end of block reached // Update prev_word_best_choice pointer.