int16_t BLOCK_LINE_IT::get_line( //get a line int16_t y, //line to get int16_t &xext //output extent ) { ICOORD bleft; //bounding box ICOORD tright; //of block & rect //get block box block->bounding_box (bleft, tright); if (y < bleft.y () || y >= tright.y ()) { // block->print(stderr,false); BADBLOCKLINE.error ("BLOCK_LINE_IT::get_line", ABORT, "Y=%d", y); } //get rectangle box rect_it.bounding_box (bleft, tright); //inside rectangle if (y >= bleft.y () && y < tright.y ()) { //width of line xext = tright.x () - bleft.x (); return bleft.x (); //start of line } for (rect_it.start_block (); !rect_it.cycled_rects (); rect_it.forward ()) { //get rectangle box rect_it.bounding_box (bleft, tright); //inside rectangle if (y >= bleft.y () && y < tright.y ()) { //width of line xext = tright.x () - bleft.x (); return bleft.x (); //start of line } } LOSTBLOCKLINE.error ("BLOCK_LINE_IT::get_line", ABORT, "Y=%d", y); return 0; //dummy to stop warning }
void ELIST2::assign_to_sublist( //to this list ELIST2_ITERATOR *start_it, //from list start ELIST2_ITERATOR *end_it) { //from list end const ERRCODE LIST_NOT_EMPTY = "Destination list must be empty before extracting a sublist"; if (!empty ()) LIST_NOT_EMPTY.error ("ELIST2.assign_to_sublist", ABORT, NULL); last = start_it->extract_sublist (end_it); }
ScrollView::Color check_path_legal( //certify outline CRACKEDGE *start //start of loop ) { int lastchain; //last chain code int chaindiff; //chain code diff inT32 length; //length of loop inT32 chainsum; //sum of chain diffs CRACKEDGE *edgept; //current point const ERRCODE ED_ILLEGAL_SUM = "Illegal sum of chain codes"; length = 0; chainsum = 0; //sum of chain codes edgept = start; lastchain = edgept->prev->stepdir; //previous chain code do { length++; if (edgept->stepdir != lastchain) { //chain code difference chaindiff = edgept->stepdir - lastchain; if (chaindiff > 2) chaindiff -= 4; else if (chaindiff < -2) chaindiff += 4; chainsum += chaindiff; //sum differences lastchain = edgept->stepdir; } edgept = edgept->next; } while (edgept != start && length < edges_maxedgelength); if ((chainsum != 4 && chainsum != -4) || edgept != start || length < MINEDGELENGTH) { if (edgept != start) { long_edges++; return ScrollView::YELLOW; } else if (length < MINEDGELENGTH) { short_edges++; return ScrollView::MAGENTA; } else { ED_ILLEGAL_SUM.error ("check_path_legal", TESSLOG, "chainsum=%d", chainsum); return ScrollView::GREEN; } } //colour on inside return chainsum < 0 ? ScrollView::BLUE : ScrollView::RED; }
void ELIST::assign_to_sublist( //to this list ELIST_ITERATOR *start_it, //from list start ELIST_ITERATOR *end_it) { //from list end const ERRCODE LIST_NOT_EMPTY = "Destination list must be empty before extracting a sublist"; #ifndef NDEBUG if (!this) NULL_OBJECT.error ("ELIST::assign_to_sublist", ABORT, NULL); #endif if (!empty ()) LIST_NOT_EMPTY.error ("ELIST.assign_to_sublist", ABORT, NULL); last = start_it->extract_sublist (end_it); }
void LLSQ::remove(double x, double y) { // delete an element if (total_weight <= 0.0) // illegal EMPTY_LLSQ.error("LLSQ::remove", ABORT, NULL); total_weight--; // count elements sigx -= x; // update accumulators sigy -= y; sigxx -= x * x; sigxy -= x * y; sigyy -= y * y; }
/********************************************************************** * error * * Print an error message and continue, exit or abort according to action. * Makes use of error messages and numbers in a common place. * **********************************************************************/ void ERRCODE::error( // handle error const char *caller, // name of caller TessErrorLogCode action, // action to take const char *format, ... // special message ) const { va_list args; // variable args char msg[MAX_MSG]; char *msgptr = msg; if (caller != nullptr) //name of caller msgptr += sprintf (msgptr, "%s:", caller); //actual message msgptr += sprintf (msgptr, "Error:%s", message); if (format != nullptr) { msgptr += sprintf (msgptr, ":"); va_start(args, format); //variable list #ifdef _WIN32 //print remainder msgptr += _vsnprintf (msgptr, MAX_MSG - 2 - (msgptr - msg), format, args); msg[MAX_MSG - 2] = '\0'; //ensure termination strcat (msg, "\n"); #else //print remainder msgptr += vsprintf (msgptr, format, args); //no specific msgptr += sprintf (msgptr, "\n"); #endif va_end(args); } else //no specific msgptr += sprintf (msgptr, "\n"); // %s is needed here so msg is printed correctly! fprintf(stderr, "%s", msg); int* p = nullptr; switch (action) { case DBG: case TESSLOG: return; //report only case TESSEXIT: //err_exit(); case ABORT: // Create a deliberate segv as the stack trace is more useful that way. if (!*p) abort(); default: BADERRACTION.error ("error", ABORT, nullptr); } }
VARIABLES_WINDOW *ASSOCIATION_LIST::lookup( //find assoc WINDOW fd //Window handle ) { ASSOC_IT it(&associations); if (!it.empty ()) { for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { if (fd == it.data ()->fd) return it.data ()->var_win; } } NOT_ASSOCIATED.error ("ASSOCIATION_LIST::lookup", ABORT, NULL); return NULL; }
void ASSOCIATION_LIST::remove( // delete assoc WINDOW fd //Window handle ) { ASSOC_IT it(&associations); if (!it.empty ()) { for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { if (fd == it.data ()->fd) { it.extract (); return; } } } NOT_ASSOCIATED.error ("ASSOCIATION_LIST::remove", ABORT, NULL); }
void QLSQ::remove( //delete an element double x, //xcoord double y //ycoord ) { if (n <= 0) //illegal EMPTY_QLSQ.error ("QLSQ::remove", ABORT, NULL); n--; //count elements sigx -= x; //update accumulators sigy -= y; sigxx -= x * x; sigxy -= x * y; sigyy -= y * y; sigxxx -= (long double) x *x * x; sigxxy -= (long double) x *x * y; sigxxxx -= (long double) x *x * x * x; }
/********************************************************************** * error * * Print an error message and continue, exit or abort according to action. * Makes use of error messages and numbers in a common place. * **********************************************************************/ void ERRCODE::error ( //handle error const char *caller, //name of caller inT8 action, //action to take const char *format, ... //special message ) const { va_list args; //variable args char msg[MAX_MSG]; char *msgptr = msg; if (caller != NULL) //name of caller msgptr += sprintf (msgptr, "%s:", caller); //actual message msgptr += sprintf (msgptr, "Error:%s", message); if (format != NULL) { msgptr += sprintf (msgptr, ":"); va_start(args, format); //variable list #ifdef __MSW32__ //print remainder msgptr += _vsnprintf (msgptr, MAX_MSG - 2 - (msgptr - msg), format, args); msg[MAX_MSG - 2] = '\0'; //ensure termination strcat (msg, "\n"); #else //print remainder msgptr += vsprintf (msgptr, format, args); //no specific msgptr += sprintf (msgptr, "\n"); #endif va_end(args); } else //no specific msgptr += sprintf (msgptr, "\n"); fprintf(stderr, msg); /*if ((strstr (message, "File") != NULL) || (strstr (message, "file") != NULL)) else if ((strstr (message, "List") != NULL) || (strstr (message, "list") != NULL)) else if ((strstr (message, "Memory") != NULL) || (strstr (message, "memory") != NULL)) global_abort_code = MEMORY_ABORT; else global_abort_code = NO_ABORT_CODE; */ int* p = NULL; switch (action) { case DBG: case TESSLOG: return; //report only case TESSEXIT: //err_exit(); case ABORT: // Create a deliberate segv as the stack trace is more useful that way. if (!*p) abort(); default: BADERRACTION.error ("error", ABORT, NULL); } }
ELIST2_LINK *ELIST2_ITERATOR::extract_sublist( //from this current ELIST2_ITERATOR *other_it) { //to other current #ifndef NDEBUG const ERRCODE BAD_EXTRACTION_PTS = "Can't extract sublist from points on different lists"; const ERRCODE DONT_EXTRACT_DELETED = "Can't extract a sublist marked by deleted points"; #endif const ERRCODE BAD_SUBLIST = "Can't find sublist end point in original list"; ELIST2_ITERATOR temp_it = *this; ELIST2_LINK *end_of_new_list; #ifndef NDEBUG if (!other_it) BAD_PARAMETER.error ("ELIST2_ITERATOR::extract_sublist", ABORT, "other_it NULL"); if (!list) NO_LIST.error ("ELIST2_ITERATOR::extract_sublist", ABORT, NULL); if (list != other_it->list) BAD_EXTRACTION_PTS.error ("ELIST2_ITERATOR.extract_sublist", ABORT, NULL); if (list->empty ()) EMPTY_LIST.error ("ELIST2_ITERATOR::extract_sublist", ABORT, NULL); if (!current || !other_it->current) DONT_EXTRACT_DELETED.error ("ELIST2_ITERATOR.extract_sublist", ABORT, NULL); #endif ex_current_was_last = other_it->ex_current_was_last = FALSE; ex_current_was_cycle_pt = FALSE; other_it->ex_current_was_cycle_pt = FALSE; temp_it.mark_cycle_pt (); do { //walk sublist if (temp_it.cycled_list ()) //can't find end pt BAD_SUBLIST.error ("ELIST2_ITERATOR.extract_sublist", ABORT, NULL); if (temp_it.at_last ()) { list->last = prev; ex_current_was_last = other_it->ex_current_was_last = TRUE; } if (temp_it.current == cycle_pt) ex_current_was_cycle_pt = TRUE; if (temp_it.current == other_it->cycle_pt) other_it->ex_current_was_cycle_pt = TRUE; temp_it.forward (); } //do INCLUSIVE list while (temp_it.prev != other_it->current); //circularise sublist other_it->current->next = current; //circularise sublist current->prev = other_it->current; end_of_new_list = other_it->current; //sublist = whole list if (prev == other_it->current) { list->last = NULL; prev = current = next = NULL; other_it->prev = other_it->current = other_it->next = NULL; } else { prev->next = other_it->next; other_it->next->prev = prev; current = other_it->current = NULL; next = other_it->next; other_it->prev = prev; } return end_of_new_list; }
void ELIST2_ITERATOR::exchange( //positions of 2 links ELIST2_ITERATOR *other_it) { //other iterator const ERRCODE DONT_EXCHANGE_DELETED = "Can't exchange deleted elements of lists"; ELIST2_LINK *old_current; #ifndef NDEBUG if (!list) NO_LIST.error ("ELIST2_ITERATOR::exchange", ABORT, NULL); if (!other_it) BAD_PARAMETER.error ("ELIST2_ITERATOR::exchange", ABORT, "other_it NULL"); if (!(other_it->list)) NO_LIST.error ("ELIST2_ITERATOR::exchange", ABORT, "other_it"); #endif /* Do nothing if either list is empty or if both iterators reference the same link */ if ((list->empty ()) || (other_it->list->empty ()) || (current == other_it->current)) return; /* Error if either current element is deleted */ if (!current || !other_it->current) DONT_EXCHANGE_DELETED.error ("ELIST2_ITERATOR.exchange", ABORT, NULL); /* Now handle the 4 cases: doubleton list; non-doubleton adjacent elements (other before this); non-doubleton adjacent elements (this before other); non-adjacent elements. */ //adjacent links if ((next == other_it->current) || (other_it->next == current)) { //doubleton list if ((next == other_it->current) && (other_it->next == current)) { prev = next = current; other_it->prev = other_it->next = other_it->current; } else { //non-doubleton with //adjacent links //other before this if (other_it->next == current) { other_it->prev->next = current; other_it->current->next = next; other_it->current->prev = current; current->next = other_it->current; current->prev = other_it->prev; next->prev = other_it->current; other_it->next = other_it->current; prev = current; } else { //this before other prev->next = other_it->current; current->next = other_it->next; current->prev = other_it->current; other_it->current->next = current; other_it->current->prev = prev; other_it->next->prev = current; next = current; other_it->prev = other_it->current; } } } else { //no overlap prev->next = other_it->current; current->next = other_it->next; current->prev = other_it->prev; next->prev = other_it->current; other_it->prev->next = current; other_it->current->next = next; other_it->current->prev = prev; other_it->next->prev = current; } /* update end of list pointer when necessary (remember that the 2 iterators may iterate over different lists!) */ if (list->last == current) list->last = other_it->current; if (other_it->list->last == other_it->current) other_it->list->last = current; if (current == cycle_pt) cycle_pt = other_it->cycle_pt; if (other_it->current == other_it->cycle_pt) other_it->cycle_pt = cycle_pt; /* The actual exchange - in all cases*/ old_current = current; current = other_it->current; other_it->current = old_current; }