36 int16_t ymin, int16_t xmax,
38 : pdblk(xmin, ymin, xmax, ymax),
40 re_rotation_(1.0f, 0.0f),
41 classify_rotation_(1.0f, 0.0f),
43 ICOORDELT_IT left_it = &pdblk.leftside;
44 ICOORDELT_IT right_it = &pdblk.rightside;
47 right_to_left_ =
false;
51 cell_over_xheight_ = 2.0f;
52 pdblk.hand_poly =
nullptr;
53 left_it.set_to_list (&pdblk.leftside);
54 right_it.set_to_list (&pdblk.rightside);
56 left_it.add_to_end (
new ICOORDELT (xmin, ymin));
57 left_it.add_to_end (
new ICOORDELT (xmin, ymax));
58 right_it.add_to_end (
new ICOORDELT (xmax, ymin));
59 right_it.add_to_end (
new ICOORDELT (xmax, ymax));
68 static int decreasing_top_order(
const void *row1,
const void *row2) {
69 return (*reinterpret_cast<ROW* const*>(row2))->bounding_box().top() -
70 (*
reinterpret_cast<ROW* const*
>(row1))->bounding_box().top();
89 ROW_IT it(const_cast<ROW_LIST*>(&rows));
90 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
91 box += it.data()->restricted_bounding_box(upper_dots, lower_dots);
114 ROW_IT row_it(&rows);
116 row_it.sort (decreasing_top_order);
128 #define ROW_SPACING 5 130 ROW_IT row_it(&rows);
134 ICOORDELT_IT icoordelt_it;
140 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
141 row = row_it.data ();
198 tprintf (
"Proportional= %s\n", proportional ?
"TRUE" :
"FALSE");
199 tprintf (
"Kerning= %d\n", kerning);
200 tprintf (
"Spacing= %d\n", spacing);
201 tprintf (
"Fixed_pitch=%d\n", pitch);
205 tprintf (
"Left side coords are:\n");
206 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
207 tprintf (
"(%d,%d) ", it.data ()->x (), it.data ()->y ());
209 tprintf (
"Right side coords are:\n");
211 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
212 tprintf (
"(%d,%d) ", it.data ()->x (), it.data ()->y ());
228 proportional = source.proportional;
229 kerning = source.kerning;
230 spacing = source.spacing;
231 filename = source.filename;
234 re_rotation_ = source.re_rotation_;
235 classify_rotation_ = source.classify_rotation_;
236 skew_ = source.skew_;
250 static bool LeftMargin(ICOORDELT_LIST *segments,
int x,
int *margin) {
253 if (segments->empty())
255 ICOORDELT_IT seg_it(segments);
256 for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) {
257 int cur_margin = x - seg_it.data()->x();
258 if (cur_margin >= 0) {
260 *margin = cur_margin;
261 }
else if (cur_margin < *margin) {
262 *margin = cur_margin;
280 static bool RightMargin(ICOORDELT_LIST *segments,
int x,
int *margin) {
283 if (segments->empty())
285 ICOORDELT_IT seg_it(segments);
286 for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) {
287 int cur_margin = seg_it.data()->x() + seg_it.data()->y() - x;
288 if (cur_margin >= 0) {
290 *margin = cur_margin;
291 }
else if (cur_margin < *margin) {
292 *margin = cur_margin;
343 ROW *first_row = r_it.data();
344 ROW *second_row = r_it.data_relative(1);
352 WERD_IT werd_it(r_it.data()->word_list());
353 if (!werd_it.empty()) {
354 C_BLOB_IT cblob_it(werd_it.data()->cblob_list());
355 for (cblob_it.mark_cycle_pt(); !cblob_it.cycled_list();
356 cblob_it.forward()) {
357 TBOX bbox = cblob_it.data()->bounding_box();
358 if (bbox.
bottom() <= mid_second_line) {
361 if (drop_cap_bottom > bbox.
bottom())
362 drop_cap_bottom = bbox.
bottom();
363 if (drop_cap_right < bbox.
right())
364 drop_cap_right = bbox.
right();
373 for (r_it.mark_cycle_pt(); !r_it.cycled_list(); r_it.forward()) {
374 ROW *row = r_it.data();
378 const std::unique_ptr< ICOORDELT_LIST> segments_left(
380 LeftMargin(segments_left.get(), row_box.
left(), &left_margin);
382 if (row_box.
top() >= drop_cap_bottom) {
383 int drop_cap_distance = row_box.
left() - row->
space() - drop_cap_right;
384 if (drop_cap_distance < 0)
385 drop_cap_distance = 0;
386 if (drop_cap_distance < left_margin)
387 left_margin = drop_cap_distance;
392 const std::unique_ptr< ICOORDELT_LIST> segments_right(
394 RightMargin(segments_right.get(), row_box.
right(), &right_margin);
411 BLOCK_IT block_it(block_list);
412 for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
413 BLOCK* block = block_it.data();
416 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
418 ROW* row = row_it.data();
421 for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
422 WERD* werd = werd_it.data();
428 tprintf(
"Block list stats:\nBlocks = %d\nRows = %d\nWords = %d\nBlobs = %d\n",
429 num_blocks, num_rows, num_words, num_blobs);
440 C_BLOB_LIST* output_blob_list) {
441 C_BLOB_IT return_list_it(output_blob_list);
442 BLOCK_IT block_it(blocks);
443 for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
444 BLOCK* block = block_it.data();
446 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
447 ROW* row = row_it.data();
450 for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
451 WERD* werd = werd_it.data();
452 return_list_it.move_to_last();
453 return_list_it.add_list_after(werd->
cblob_list());
454 return_list_it.move_to_last();
475 C_BLOB_LIST* new_blobs,
476 C_BLOB_LIST* not_found_blobs) {
479 BLOCK_IT block_it(block_list);
480 for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
481 BLOCK* block = block_it.data();
486 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
487 ROW* row = row_it.data();
491 WERD_IT new_words_it(&new_words);
492 for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
493 WERD* werd = werd_it.extract();
499 new_words_it.add_after_then_move(new_werd);
505 new_words_it.add_after_then_move(werd);
510 werd_it.move_to_first();
511 werd_it.add_list_after(&new_words);
void print(FILE *fp, bool dump)
dump whole table
void operator=(const ELIST_LINK &)
ICOORDELT_LIST leftside
left side vertices
void rotate(FCOORD rotation)
void set_lmargin(int16_t lmargin)
ICOORDELT_LIST rightside
right side vertices
void reflect_polygon_in_y_axis()
void compress()
shrink white space
void sort_rows()
decreasing y order
void PrintSegmentationStats(BLOCK_LIST *block_list)
POLY_BLOCK * poly_block() const
C_BLOB_LIST * rej_cblob_list()
void ExtractBlobsFromSegmentation(BLOCK_LIST *blocks, C_BLOB_LIST *output_blob_list)
void check_pitch()
check proportional
void rotate(const FCOORD &rotation)
void move(const ICOORD vec)
void set_has_drop_cap(bool has)
const ICOORD & botleft() const
void bounding_box(ICOORD &bottom_left, ICOORD &top_right) const
get box
void move_bottom_edge(const int16_t y)
TBOX restricted_bounding_box(bool upper_dots, bool lower_dots) const
#define ELISTIZE(CLASSNAME)
const char * string() const
DLLSYM void tprintf(const char *format,...)
void compute_row_margins()
PDBLK pdblk
Page Description Block.
ICOORDELT_LIST * get_line(int16_t y)
void set_rmargin(int16_t rmargin)
BLOCK & operator=(const BLOCK &source)
float base_line(float xpos) const
WERD * ConstructWerdWithNewBlobs(C_BLOB_LIST *all_blobs, C_BLOB_LIST *orphan_blobs)
void RefreshWordBlobsFromNewBlobs(BLOCK_LIST *block_list, C_BLOB_LIST *new_blobs, C_BLOB_LIST *not_found_blobs)
TBOX bounding_box() const
ROW_LIST * row_list()
get rows
void move(const ICOORD vec)
C_BLOB_LIST * cblob_list()