tesseract  4.0.0-1-g2a2b
fpchop.cpp File Reference
#include "blobbox.h"
#include "statistc.h"
#include "drawtord.h"
#include "tovars.h"
#include "topitch.h"
#include "fpchop.h"

Go to the source code of this file.

Macros

#define EXTERN
 

Functions

ROWfixed_pitch_words (TO_ROW *row, FCOORD rotation)
 
WERDadd_repeated_word (WERD_IT *rep_it, int16_t &rep_left, int16_t &prev_chop_coord, uint8_t &blanks, float pitch, WERD_IT *word_it)
 
void split_to_blob (BLOBNBOX *blob, int16_t chop_coord, float pitch_error, C_OUTLINE_LIST *left_coutlines, C_OUTLINE_LIST *right_coutlines)
 
void fixed_chop_cblob (C_BLOB *blob, int16_t chop_coord, float pitch_error, C_OUTLINE_LIST *left_outlines, C_OUTLINE_LIST *right_outlines)
 
void fixed_split_coutline (C_OUTLINE *srcline, int16_t chop_coord, float pitch_error, C_OUTLINE_IT *left_it, C_OUTLINE_IT *right_it)
 
bool fixed_chop_coutline (C_OUTLINE *srcline, int16_t chop_coord, float pitch_error, C_OUTLINE_FRAG_LIST *left_frags, C_OUTLINE_FRAG_LIST *right_frags)
 
void save_chop_cfragment (int16_t head_index, ICOORD head_pos, int16_t tail_index, ICOORD tail_pos, C_OUTLINE *srcline, C_OUTLINE_FRAG_LIST *frags)
 
void add_frag_to_list (C_OUTLINE_FRAG *frag, C_OUTLINE_FRAG_LIST *frags)
 
void close_chopped_cfragments (C_OUTLINE_FRAG_LIST *frags, C_OUTLINE_LIST *children, float pitch_error, C_OUTLINE_IT *dest_it)
 
C_OUTLINEjoin_chopped_fragments (C_OUTLINE_FRAG *bottom, C_OUTLINE_FRAG *top)
 
void join_segments (C_OUTLINE_FRAG *bottom, C_OUTLINE_FRAG *top)
 

Variables

EXTERN int textord_fp_chop_error = 2
 
EXTERN double textord_fp_chop_snap = 0.5
 

Macro Definition Documentation

◆ EXTERN

#define EXTERN

Definition at line 32 of file fpchop.cpp.

Function Documentation

◆ add_frag_to_list()

void add_frag_to_list ( C_OUTLINE_FRAG frag,
C_OUTLINE_FRAG_LIST *  frags 
)

Definition at line 605 of file fpchop.cpp.

608  {
609  //output list
610  C_OUTLINE_FRAG_IT frag_it = frags;
611 
612  if (!frags->empty ()) {
613  for (frag_it.mark_cycle_pt (); !frag_it.cycled_list ();
614  frag_it.forward ()) {
615  if (frag_it.data ()->ycoord > frag->ycoord
616  || (frag_it.data ()->ycoord == frag->ycoord
617  && frag->other_end->ycoord < frag->ycoord)) {
618  frag_it.add_before_then_move (frag);
619  return;
620  }
621  }
622  }
623  frag_it.add_to_end (frag);
624 }
C_OUTLINE_FRAG * other_end
Definition: fpchop.h:51
int16_t ycoord
Definition: fpchop.h:52

◆ add_repeated_word()

WERD* add_repeated_word ( WERD_IT *  rep_it,
int16_t &  rep_left,
int16_t &  prev_chop_coord,
uint8_t &  blanks,
float  pitch,
WERD_IT *  word_it 
)

Definition at line 203 of file fpchop.cpp.

210  {
211  WERD *word; //word to move
212  int16_t new_blanks; //extra blanks
213 
214  if (rep_left > prev_chop_coord) {
215  new_blanks = (uint8_t) floor ((rep_left - prev_chop_coord) / pitch + 0.5);
216  blanks += new_blanks;
217  }
218  word = rep_it->extract ();
219  prev_chop_coord = word->bounding_box ().right ();
220  word_it->add_after_then_move (word);
221  word->set_blanks (blanks);
222  rep_it->forward ();
223  if (rep_it->empty ())
224  rep_left = INT16_MAX;
225  else
226  rep_left = rep_it->data ()->bounding_box ().left ();
227  blanks = 0;
228  return word;
229 }
TBOX bounding_box() const
Definition: werd.cpp:159
void set_blanks(uint8_t new_blanks)
Definition: werd.h:105
Definition: werd.h:59
int16_t right() const
Definition: rect.h:79

◆ close_chopped_cfragments()

void close_chopped_cfragments ( C_OUTLINE_FRAG_LIST *  frags,
C_OUTLINE_LIST *  children,
float  pitch_error,
C_OUTLINE_IT *  dest_it 
)

Definition at line 634 of file fpchop.cpp.

639  {
640  //iterator
641  C_OUTLINE_FRAG_IT frag_it = frags;
642  C_OUTLINE_FRAG *bottom_frag; //bottom of cut
643  C_OUTLINE_FRAG *top_frag; //top of cut
644  C_OUTLINE *outline; //new outline
645  C_OUTLINE *child; //current child
646  C_OUTLINE_IT child_it = children;
647  C_OUTLINE_IT olchild_it; //children of outline
648 
649  while (!frag_it.empty()) {
650  frag_it.move_to_first();
651  // get bottom one
652  bottom_frag = frag_it.extract();
653  frag_it.forward();
654  top_frag = frag_it.data(); // look at next
655  if ((bottom_frag->steps == nullptr && top_frag->steps == nullptr)
656  || (bottom_frag->steps != nullptr && top_frag->steps != nullptr)) {
657  if (frag_it.data_relative(1)->ycoord == top_frag->ycoord)
658  frag_it.forward();
659  }
660  top_frag = frag_it.extract();
661  if (top_frag->other_end != bottom_frag) {
662  outline = join_chopped_fragments(bottom_frag, top_frag);
663  ASSERT_HOST(outline == nullptr);
664  } else {
665  outline = join_chopped_fragments(bottom_frag, top_frag);
666  if (outline != nullptr) {
667  olchild_it.set_to_list(outline->child());
668  for (child_it.mark_cycle_pt(); !child_it.cycled_list();
669  child_it.forward()) {
670  child = child_it.data();
671  if (*child < *outline)
672  olchild_it.add_to_end(child_it.extract());
673  }
674  if (outline->bounding_box().width() > pitch_error)
675  dest_it->add_after_then_move(outline);
676  else
677  delete outline; // Make it disappear.
678  }
679  }
680  }
681  while (!child_it.empty ()) {
682  dest_it->add_after_then_move (child_it.extract ());
683  child_it.forward ();
684  }
685 }
C_OUTLINE_FRAG * other_end
Definition: fpchop.h:51
int16_t ycoord
Definition: fpchop.h:52
int16_t width() const
Definition: rect.h:115
C_OUTLINE * join_chopped_fragments(C_OUTLINE_FRAG *bottom, C_OUTLINE_FRAG *top)
Definition: fpchop.cpp:695
const TBOX & bounding_box() const
Definition: coutln.h:113
C_OUTLINE_LIST * child()
Definition: coutln.h:108
DIR128 * steps
Definition: fpchop.h:49
#define ASSERT_HOST(x)
Definition: errcode.h:84

◆ fixed_chop_cblob()

void fixed_chop_cblob ( C_BLOB blob,
int16_t  chop_coord,
float  pitch_error,
C_OUTLINE_LIST *  left_outlines,
C_OUTLINE_LIST *  right_outlines 
)

Definition at line 269 of file fpchop.cpp.

275  {
276  C_OUTLINE *old_right; //already there
277  C_OUTLINE_LIST new_outlines; //new right ones
278  //output iterator
279  C_OUTLINE_IT left_it = left_outlines;
280  //in/out iterator
281  C_OUTLINE_IT right_it = right_outlines;
282  C_OUTLINE_IT new_it = &new_outlines;
283  C_OUTLINE_IT blob_it; //outlines in blob
284 
285  if (!right_it.empty ()) {
286  while (!right_it.empty ()) {
287  old_right = right_it.extract ();
288  right_it.forward ();
289  fixed_split_coutline(old_right,
290  chop_coord,
291  pitch_error,
292  &left_it,
293  &new_it);
294  }
295  right_it.add_list_before (&new_outlines);
296  }
297  if (blob != nullptr) {
298  blob_it.set_to_list (blob->out_list ());
299  for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
300  blob_it.forward ())
301  fixed_split_coutline (blob_it.extract (), chop_coord, pitch_error,
302  &left_it, &right_it);
303  delete blob;
304  }
305 }
void fixed_split_coutline(C_OUTLINE *srcline, int16_t chop_coord, float pitch_error, C_OUTLINE_IT *left_it, C_OUTLINE_IT *right_it)
Definition: fpchop.cpp:315
C_OUTLINE_LIST * out_list()
Definition: stepblob.h:70

◆ fixed_chop_coutline()

bool fixed_chop_coutline ( C_OUTLINE srcline,
int16_t  chop_coord,
float  pitch_error,
C_OUTLINE_FRAG_LIST *  left_frags,
C_OUTLINE_FRAG_LIST *  right_frags 
)

Definition at line 397 of file fpchop.cpp.

403  {
404  bool first_frag; //fragment
405  int16_t left_edge; //of outline
406  int16_t startindex; //in first fragment
407  int32_t length; //of outline
408  int16_t stepindex; //into outline
409  int16_t head_index; //start of fragment
410  ICOORD head_pos; //start of fragment
411  int16_t tail_index; //end of fragment
412  ICOORD tail_pos; //end of fragment
413  ICOORD pos; //current point
414  int16_t first_index = 0; //first tail
415  ICOORD first_pos; //first tail
416 
417  length = srcline->pathlength ();
418  pos = srcline->start_pos ();
419  left_edge = pos.x ();
420  tail_index = 0;
421  tail_pos = pos;
422  for (stepindex = 0; stepindex < length; stepindex++) {
423  if (pos.x () < left_edge) {
424  left_edge = pos.x ();
425  tail_index = stepindex;
426  tail_pos = pos;
427  }
428  pos += srcline->step (stepindex);
429  }
430  if (left_edge >= chop_coord - pitch_error)
431  return false; //not worth it
432 
433  startindex = tail_index;
434  first_frag = true;
435  head_index = tail_index;
436  head_pos = tail_pos;
437  do {
438  do {
439  tail_pos += srcline->step (tail_index);
440  tail_index++;
441  if (tail_index == length)
442  tail_index = 0;
443  }
444  while (tail_pos.x () != chop_coord && tail_index != startindex);
445  if (tail_index == startindex) {
446  if (first_frag)
447  return false; //doesn't cross line
448  else
449  break;
450  }
451  ASSERT_HOST (head_index != tail_index);
452  if (!first_frag) {
453  save_chop_cfragment(head_index,
454  head_pos,
455  tail_index,
456  tail_pos,
457  srcline,
458  left_frags);
459  }
460  else {
461  first_index = tail_index;
462  first_pos = tail_pos;
463  first_frag = false;
464  }
465  while (srcline->step (tail_index).x () == 0) {
466  tail_pos += srcline->step (tail_index);
467  tail_index++;
468  if (tail_index == length)
469  tail_index = 0;
470  }
471  head_index = tail_index;
472  head_pos = tail_pos;
473  while (srcline->step (tail_index).x () > 0) {
474  do {
475  tail_pos += srcline->step (tail_index);
476  tail_index++;
477  if (tail_index == length)
478  tail_index = 0;
479  }
480  while (tail_pos.x () != chop_coord);
481  ASSERT_HOST (head_index != tail_index);
482  save_chop_cfragment(head_index,
483  head_pos,
484  tail_index,
485  tail_pos,
486  srcline,
487  right_frags);
488  while (srcline->step (tail_index).x () == 0) {
489  tail_pos += srcline->step (tail_index);
490  tail_index++;
491  if (tail_index == length)
492  tail_index = 0;
493  }
494  head_index = tail_index;
495  head_pos = tail_pos;
496  }
497  }
498  while (tail_index != startindex);
499  save_chop_cfragment(head_index,
500  head_pos,
501  first_index,
502  first_pos,
503  srcline,
504  left_frags);
505  return true; //did some chopping
506 }
void save_chop_cfragment(int16_t head_index, ICOORD head_pos, int16_t tail_index, ICOORD tail_pos, C_OUTLINE *srcline, C_OUTLINE_FRAG_LIST *frags)
Definition: fpchop.cpp:514
const ICOORD & start_pos() const
Definition: coutln.h:148
integer coordinate
Definition: points.h:32
int16_t x() const
access function
Definition: points.h:53
int32_t pathlength() const
Definition: coutln.h:135
ICOORD step(int index) const
Definition: coutln.h:144
#define ASSERT_HOST(x)
Definition: errcode.h:84

◆ fixed_pitch_words()

ROW* fixed_pitch_words ( TO_ROW row,
FCOORD  rotation 
)

Definition at line 47 of file fpchop.cpp.

50  {
51  bool bol; //start of line
52  uint8_t blanks; //in front of word
53  uint8_t new_blanks; //blanks in empty cell
54  int16_t chop_coord; //chop boundary
55  int16_t prev_chop_coord; //start of cell
56  int16_t rep_left; //left edge of rep word
57  ROW *real_row; //output row
58  C_OUTLINE_LIST left_coutlines;
59  C_OUTLINE_LIST right_coutlines;
60  C_BLOB_LIST cblobs;
61  C_BLOB_IT cblob_it = &cblobs;
62  WERD_LIST words;
63  WERD_IT word_it = &words; //new words
64  //repeated blobs
65  WERD_IT rep_it = &row->rep_words;
66  WERD *word; //new word
67  int32_t xstarts[2]; //row ends
68  int32_t prev_x; //end of prev blob
69  //iterator
70  BLOBNBOX_IT box_it = row->blob_list ();
71  //boundaries
72  ICOORDELT_IT cell_it = &row->char_cells;
73 
74 #ifndef GRAPHICS_DISABLED
75  if (textord_show_page_cuts && to_win != nullptr) {
77  }
78 #endif
79 
80  prev_x = -INT16_MAX;
81  bol = true;
82  blanks = 0;
83  if (rep_it.empty ())
84  rep_left = INT16_MAX;
85  else
86  rep_left = rep_it.data ()->bounding_box ().left ();
87  if (box_it.empty ())
88  return nullptr; //empty row
89  xstarts[0] = box_it.data ()->bounding_box ().left ();
90  if (rep_left < xstarts[0]) {
91  xstarts[0] = rep_left;
92  }
93  if (cell_it.empty () || row->char_cells.singleton ()) {
94  tprintf ("Row without enough char cells!\n");
95  tprintf ("Leftmost blob is at (%d,%d)\n",
96  box_it.data ()->bounding_box ().left (),
97  box_it.data ()->bounding_box ().bottom ());
98  return nullptr;
99  }
100  ASSERT_HOST (!cell_it.empty () && !row->char_cells.singleton ());
101  prev_chop_coord = cell_it.data ()->x ();
102  word = nullptr;
103  while (rep_left < cell_it.data ()->x ()) {
104  word = add_repeated_word (&rep_it, rep_left, prev_chop_coord,
105  blanks, row->fixed_pitch, &word_it);
106  }
107  cell_it.mark_cycle_pt ();
108  if (prev_chop_coord >= cell_it.data ()->x ())
109  cell_it.forward ();
110  for (; !cell_it.cycled_list (); cell_it.forward ()) {
111  chop_coord = cell_it.data ()->x ();
112  while (!box_it.empty ()
113  && box_it.data ()->bounding_box ().left () <= chop_coord) {
114  if (box_it.data ()->bounding_box ().right () > prev_x)
115  prev_x = box_it.data ()->bounding_box ().right ();
116  split_to_blob (box_it.extract (), chop_coord,
117  textord_fp_chop_error + 0.5f,
118  &left_coutlines,
119  &right_coutlines);
120  box_it.forward ();
121  while (!box_it.empty() && box_it.data()->cblob() == nullptr) {
122  delete box_it.extract();
123  box_it.forward();
124  }
125  }
126  if (!right_coutlines.empty() && left_coutlines.empty())
127  split_to_blob (nullptr, chop_coord,
128  textord_fp_chop_error + 0.5f,
129  &left_coutlines,
130  &right_coutlines);
131  if (!left_coutlines.empty()) {
132  cblob_it.add_after_then_move(new C_BLOB(&left_coutlines));
133  } else {
134  if (rep_left < chop_coord) {
135  if (rep_left > prev_chop_coord)
136  new_blanks = (uint8_t) floor ((rep_left - prev_chop_coord)
137  / row->fixed_pitch + 0.5);
138  else
139  new_blanks = 0;
140  }
141  else {
142  if (chop_coord > prev_chop_coord)
143  new_blanks = (uint8_t) floor ((chop_coord - prev_chop_coord)
144  / row->fixed_pitch + 0.5);
145  else
146  new_blanks = 0;
147  }
148  if (!cblob_it.empty()) {
149  if (blanks < 1 && word != nullptr && !word->flag (W_REP_CHAR))
150  blanks = 1;
151  word = new WERD (&cblobs, blanks, nullptr);
152  cblob_it.set_to_list (&cblobs);
153  word->set_flag (W_DONT_CHOP, TRUE);
154  word_it.add_after_then_move (word);
155  if (bol) {
156  word->set_flag (W_BOL, TRUE);
157  bol = false;
158  }
159  blanks = new_blanks;
160  }
161  else
162  blanks += new_blanks;
163  while (rep_left < chop_coord) {
164  word = add_repeated_word (&rep_it, rep_left, prev_chop_coord,
165  blanks, row->fixed_pitch, &word_it);
166  }
167  }
168  if (prev_chop_coord < chop_coord)
169  prev_chop_coord = chop_coord;
170  }
171  if (!cblob_it.empty()) {
172  word = new WERD(&cblobs, blanks, nullptr);
173  word->set_flag (W_DONT_CHOP, TRUE);
174  word_it.add_after_then_move (word);
175  if (bol)
176  word->set_flag (W_BOL, TRUE);
177  }
178  ASSERT_HOST (word != nullptr);
179  while (!rep_it.empty ()) {
180  add_repeated_word (&rep_it, rep_left, prev_chop_coord,
181  blanks, row->fixed_pitch, &word_it);
182  }
183  //at end of line
184  word_it.data ()->set_flag (W_EOL, TRUE);
185  if (prev_chop_coord > prev_x)
186  prev_x = prev_chop_coord;
187  xstarts[1] = prev_x + 1;
188  real_row = new ROW (row, (int16_t) row->kern_size, (int16_t) row->space_size);
189  word_it.set_to_list (real_row->word_list ());
190  //put words in row
191  word_it.add_list_after (&words);
192  real_row->recalc_bounding_box ();
193  return real_row;
194 }
#define TRUE
Definition: capi.h:51
ICOORDELT_LIST char_cells
Definition: blobbox.h:682
EXTERN bool textord_show_page_cuts
Definition: topitch.cpp:50
float fixed_pitch
Definition: blobbox.h:664
WERD_LIST rep_words
Definition: blobbox.h:681
void split_to_blob(BLOBNBOX *blob, int16_t chop_coord, float pitch_error, C_OUTLINE_LIST *left_coutlines, C_OUTLINE_LIST *right_coutlines)
Definition: fpchop.cpp:239
WERD_LIST * word_list()
Definition: ocrrow.h:55
Definition: werd.h:35
float space_size
Definition: blobbox.h:680
void set_flag(WERD_FLAGS mask, bool value)
Definition: werd.h:127
void plot_row_cells(ScrollView *win, ScrollView::Color colour, TO_ROW *row, float xshift, ICOORDELT_LIST *cells)
Definition: drawtord.cpp:396
float kern_size
Definition: blobbox.h:679
Definition: werd.h:59
Definition: ocrrow.h:36
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:37
Definition: werd.h:34
EXTERN ScrollView * to_win
Definition: drawtord.cpp:37
void recalc_bounding_box()
Definition: ocrrow.cpp:101
WERD * add_repeated_word(WERD_IT *rep_it, int16_t &rep_left, int16_t &prev_chop_coord, uint8_t &blanks, float pitch, WERD_IT *word_it)
Definition: fpchop.cpp:203
EXTERN int textord_fp_chop_error
Definition: fpchop.cpp:35
BLOBNBOX_LIST * blob_list()
Definition: blobbox.h:612
#define ASSERT_HOST(x)
Definition: errcode.h:84

◆ fixed_split_coutline()

void fixed_split_coutline ( C_OUTLINE srcline,
int16_t  chop_coord,
float  pitch_error,
C_OUTLINE_IT *  left_it,
C_OUTLINE_IT *  right_it 
)

Definition at line 315 of file fpchop.cpp.

321  {
322  C_OUTLINE *child; //child outline
323  TBOX srcbox; //box of outline
324  C_OUTLINE_LIST left_ch; //left children
325  C_OUTLINE_LIST right_ch; //right children
326  C_OUTLINE_FRAG_LIST left_frags;//chopped fragments
327  C_OUTLINE_FRAG_LIST right_frags;;
328  C_OUTLINE_IT left_ch_it = &left_ch;
329  //for whole children
330  C_OUTLINE_IT right_ch_it = &right_ch;
331  //for holes
332  C_OUTLINE_IT child_it = srcline->child ();
333 
334  srcbox = srcline->bounding_box();
335  if (srcbox.left() + srcbox.right() <= chop_coord * 2
336  && srcbox.right() < chop_coord + pitch_error) {
337  // Whole outline is in the left side or not far over the chop_coord,
338  // so put the whole thing on the left.
339  left_it->add_after_then_move(srcline);
340  } else if (srcbox.left() + srcbox.right() > chop_coord * 2
341  && srcbox.left () > chop_coord - pitch_error) {
342  // Whole outline is in the right side or not far over the chop_coord,
343  // so put the whole thing on the right.
344  right_it->add_before_stay_put(srcline);
345  } else {
346  // Needs real chopping.
347  if (fixed_chop_coutline(srcline, chop_coord, pitch_error,
348  &left_frags, &right_frags)) {
349  for (child_it.mark_cycle_pt(); !child_it.cycled_list();
350  child_it.forward()) {
351  child = child_it.extract();
352  srcbox = child->bounding_box();
353  if (srcbox.right() < chop_coord) {
354  // Whole child is on the left.
355  left_ch_it.add_after_then_move(child);
356  } else if (srcbox.left() > chop_coord) {
357  // Whole child is on the right.
358  right_ch_it.add_after_then_move (child);
359  } else {
360  // No pitch_error is allowed when chopping children to prevent
361  // impossible outlines from being created.
362  if (fixed_chop_coutline(child, chop_coord, 0.0f,
363  &left_frags, &right_frags)) {
364  delete child;
365  } else {
366  if (srcbox.left() + srcbox.right() <= chop_coord * 2)
367  left_ch_it.add_after_then_move(child);
368  else
369  right_ch_it.add_after_then_move(child);
370  }
371  }
372  }
373  close_chopped_cfragments(&left_frags, &left_ch, pitch_error, left_it);
374  close_chopped_cfragments(&right_frags, &right_ch, pitch_error, right_it);
375  ASSERT_HOST(left_ch.empty() && right_ch.empty());
376  // No children left.
377  delete srcline; // Smashed up.
378  } else {
379  // Chop failed. Just use middle coord.
380  if (srcbox.left() + srcbox.right() <= chop_coord * 2)
381  left_it->add_after_then_move(srcline); // Stick whole in left.
382  else
383  right_it->add_before_stay_put(srcline);
384  }
385  }
386 }
Definition: rect.h:34
int16_t left() const
Definition: rect.h:72
const TBOX & bounding_box() const
Definition: coutln.h:113
C_OUTLINE_LIST * child()
Definition: coutln.h:108
void close_chopped_cfragments(C_OUTLINE_FRAG_LIST *frags, C_OUTLINE_LIST *children, float pitch_error, C_OUTLINE_IT *dest_it)
Definition: fpchop.cpp:634
int16_t right() const
Definition: rect.h:79
bool fixed_chop_coutline(C_OUTLINE *srcline, int16_t chop_coord, float pitch_error, C_OUTLINE_FRAG_LIST *left_frags, C_OUTLINE_FRAG_LIST *right_frags)
Definition: fpchop.cpp:397
#define ASSERT_HOST(x)
Definition: errcode.h:84

◆ join_chopped_fragments()

C_OUTLINE* join_chopped_fragments ( C_OUTLINE_FRAG bottom,
C_OUTLINE_FRAG top 
)

Definition at line 695 of file fpchop.cpp.

698  {
699  C_OUTLINE *outline; //closed loop
700 
701  if (bottom->other_end == top) {
702  if (bottom->steps == nullptr)
703  outline = top->close (); //turn to outline
704  else
705  outline = bottom->close ();
706  delete top;
707  delete bottom;
708  return outline;
709  }
710  if (bottom->steps == nullptr) {
711  ASSERT_HOST (top->steps != nullptr);
712  join_segments (bottom->other_end, top);
713  }
714  else {
715  ASSERT_HOST (top->steps == nullptr);
716  join_segments (top->other_end, bottom);
717  }
718  top->other_end->other_end = bottom->other_end;
719  bottom->other_end->other_end = top->other_end;
720  delete bottom;
721  delete top;
722  return nullptr;
723 }
C_OUTLINE_FRAG * other_end
Definition: fpchop.h:51
C_OUTLINE * close()
Definition: fpchop.cpp:770
DIR128 * steps
Definition: fpchop.h:49
void join_segments(C_OUTLINE_FRAG *bottom, C_OUTLINE_FRAG *top)
Definition: fpchop.cpp:732
#define ASSERT_HOST(x)
Definition: errcode.h:84

◆ join_segments()

void join_segments ( C_OUTLINE_FRAG bottom,
C_OUTLINE_FRAG top 
)

Definition at line 732 of file fpchop.cpp.

735  {
736  DIR128 *steps; //new steps
737  int32_t stepcount; //no of steps
738  int16_t fake_count; //fake steps
739  DIR128 fake_step; //step entry
740 
741  ASSERT_HOST (bottom->end.x () == top->start.x ());
742  fake_count = top->start.y () - bottom->end.y ();
743  if (fake_count < 0) {
744  fake_count = -fake_count;
745  fake_step = 32;
746  }
747  else
748  fake_step = 96;
749 
750  stepcount = bottom->stepcount + fake_count + top->stepcount;
751  steps = new DIR128[stepcount];
752  memmove (steps, bottom->steps, bottom->stepcount);
753  memset (steps + bottom->stepcount, fake_step.get_dir(), fake_count);
754  memmove (steps + bottom->stepcount + fake_count, top->steps,
755  top->stepcount);
756  delete [] bottom->steps;
757  bottom->steps = steps;
758  bottom->stepcount = stepcount;
759  bottom->end = top->end;
760  bottom->other_end->end = top->end;
761 }
C_OUTLINE_FRAG * other_end
Definition: fpchop.h:51
ICOORD end
Definition: fpchop.h:48
ICOORD start
Definition: fpchop.h:47
int16_t y() const
access_function
Definition: points.h:57
int8_t get_dir() const
Definition: mod128.h:76
int16_t x() const
access function
Definition: points.h:53
Definition: mod128.h:29
int32_t stepcount
Definition: fpchop.h:50
DIR128 * steps
Definition: fpchop.h:49
#define ASSERT_HOST(x)
Definition: errcode.h:84

◆ save_chop_cfragment()

void save_chop_cfragment ( int16_t  head_index,
ICOORD  head_pos,
int16_t  tail_index,
ICOORD  tail_pos,
C_OUTLINE srcline,
C_OUTLINE_FRAG_LIST *  frags 
)

Definition at line 514 of file fpchop.cpp.

521  {
522  int16_t jump; //gap across end
523  int16_t stepcount; //total steps
524  C_OUTLINE_FRAG *head; //head of fragment
525  C_OUTLINE_FRAG *tail; //tail of fragment
526  int16_t tail_y; //ycoord of tail
527 
528  ASSERT_HOST (tail_pos.x () == head_pos.x ());
529  ASSERT_HOST (tail_index != head_index);
530  stepcount = tail_index - head_index;
531  if (stepcount < 0)
532  stepcount += srcline->pathlength ();
533  jump = tail_pos.y () - head_pos.y ();
534  if (jump < 0)
535  jump = -jump;
536  if (jump == stepcount)
537  return; //its a nop
538  tail_y = tail_pos.y ();
539  head = new C_OUTLINE_FRAG (head_pos, tail_pos, srcline,
540  head_index, tail_index);
541  tail = new C_OUTLINE_FRAG (head, tail_y);
542  head->other_end = tail;
543  add_frag_to_list(head, frags);
544  add_frag_to_list(tail, frags);
545 }
C_OUTLINE_FRAG * other_end
Definition: fpchop.h:51
int16_t y() const
access_function
Definition: points.h:57
int16_t x() const
access function
Definition: points.h:53
int32_t pathlength() const
Definition: coutln.h:135
void add_frag_to_list(C_OUTLINE_FRAG *frag, C_OUTLINE_FRAG_LIST *frags)
Definition: fpchop.cpp:605
#define ASSERT_HOST(x)
Definition: errcode.h:84

◆ split_to_blob()

void split_to_blob ( BLOBNBOX blob,
int16_t  chop_coord,
float  pitch_error,
C_OUTLINE_LIST *  left_coutlines,
C_OUTLINE_LIST *  right_coutlines 
)

Definition at line 239 of file fpchop.cpp.

244  {
245  C_BLOB *real_cblob; //cblob to chop
246 
247  if (blob != nullptr) {
248  real_cblob = blob->cblob();
249  } else {
250  real_cblob = nullptr;
251  }
252  if (!right_coutlines->empty() || real_cblob != nullptr)
253  fixed_chop_cblob(real_cblob,
254  chop_coord,
255  pitch_error,
256  left_coutlines,
257  right_coutlines);
258 
259  delete blob;
260 }
void fixed_chop_cblob(C_BLOB *blob, int16_t chop_coord, float pitch_error, C_OUTLINE_LIST *left_outlines, C_OUTLINE_LIST *right_outlines)
Definition: fpchop.cpp:269
C_BLOB * cblob() const
Definition: blobbox.h:269

Variable Documentation

◆ textord_fp_chop_error

EXTERN int textord_fp_chop_error = 2

"Max allowed bending of chop cells"

Definition at line 35 of file fpchop.cpp.

◆ textord_fp_chop_snap

EXTERN double textord_fp_chop_snap = 0.5

"Max distance of chop pt from vertex"

Definition at line 37 of file fpchop.cpp.