42 : pdblk(xmin, ymin, xmax, ymax)
44 , re_rotation_(1.0f, 0.0f)
45 , classify_rotation_(1.0f, 0.0f)
54 cell_over_xheight_ = 2.0f;
59 left_it.add_to_end(
new ICOORDELT(xmin, ymin));
60 left_it.add_to_end(
new ICOORDELT(xmin, ymax));
61 right_it.add_to_end(
new ICOORDELT(xmax, ymin));
62 right_it.add_to_end(
new ICOORDELT(xmax, ymax));
71static int decreasing_top_order(
const void *row1,
const void *row2) {
72 return (*
reinterpret_cast<ROW *
const *
>(row2))->bounding_box().top() -
73 (*
reinterpret_cast<ROW *
const *
>(row1))->bounding_box().top();
91 ROW_IT it(
const_cast<ROW_LIST *
>(&rows));
92 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
93 box += it.data()->restricted_bounding_box(upper_dots, lower_dots);
116 ROW_IT row_it(&rows);
118 row_it.sort(decreasing_top_order);
131 ROW_IT row_it(&rows);
135 ICOORDELT_IT icoordelt_it;
141 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
195 tprintf(
"Proportional= %s\n", proportional ?
"TRUE" :
"FALSE");
196 tprintf(
"Kerning= %d\n", kerning);
197 tprintf(
"Spacing= %d\n", spacing);
198 tprintf(
"Fixed_pitch=%d\n", pitch);
199 tprintf(
"Filename= %s\n", filename.c_str());
202 tprintf(
"Left side coords are:\n");
203 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
204 tprintf(
"(%d,%d) ", it.data()->x(), it.data()->y());
207 tprintf(
"Right side coords are:\n");
209 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
210 tprintf(
"(%d,%d) ", it.data()->x(), it.data()->y());
227 proportional = source.proportional;
228 kerning = source.kerning;
229 spacing = source.spacing;
230 filename = source.filename;
234 re_rotation_ = source.re_rotation_;
235 classify_rotation_ = source.classify_rotation_;
236 skew_ = source.skew_;
250static bool LeftMargin(ICOORDELT_LIST *segments,
int x,
int *margin) {
253 if (segments->empty()) {
256 ICOORDELT_IT seg_it(segments);
257 for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) {
258 int cur_margin =
x - seg_it.data()->x();
259 if (cur_margin >= 0) {
261 *margin = cur_margin;
262 }
else if (cur_margin < *margin) {
263 *margin = cur_margin;
281static bool RightMargin(ICOORDELT_LIST *segments,
int x,
int *margin) {
284 if (segments->empty()) {
287 ICOORDELT_IT seg_it(segments);
288 for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) {
289 int cur_margin = seg_it.data()->x() + seg_it.data()->y() -
x;
290 if (cur_margin >= 0) {
292 *margin = cur_margin;
293 }
else if (cur_margin < *margin) {
294 *margin = cur_margin;
345 ROW *first_row = r_it.data();
346 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(); cblob_it.forward()) {
356 TBOX bbox = cblob_it.data()->bounding_box();
357 if (bbox.
bottom() <= mid_second_line) {
360 if (drop_cap_bottom > bbox.
bottom()) {
361 drop_cap_bottom = bbox.
bottom();
363 if (drop_cap_right < bbox.
right()) {
364 drop_cap_right = bbox.
right();
374 for (r_it.mark_cycle_pt(); !r_it.cycled_list(); r_it.forward()) {
375 ROW *row = r_it.data();
379 const std::unique_ptr< ICOORDELT_LIST> segments_left(lines.
get_line(left_y));
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;
387 if (drop_cap_distance < left_margin) {
388 left_margin = drop_cap_distance;
394 const std::unique_ptr< ICOORDELT_LIST> segments_right(lines.
get_line(right_y));
395 RightMargin(segments_right.get(), row_box.
right(), &right_margin);
412 BLOCK_IT block_it(block_list);
413 for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
414 BLOCK *block = block_it.data();
417 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
419 ROW *row = row_it.data();
422 for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
423 WERD *werd = werd_it.data();
429 tprintf(
"Block list stats:\nBlocks = %d\nRows = %d\nWords = %d\nBlobs = %d\n", num_blocks,
430 num_rows, num_words, num_blobs);
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 *not_found_blobs) {
478 BLOCK_IT block_it(block_list);
479 for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
480 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();
498 new_words_it.add_after_then_move(new_werd);
504 new_words_it.add_after_then_move(werd);
509 werd_it.move_to_first();
510 werd_it.add_list_after(&new_words);
void tprintf(const char *format,...)
void RefreshWordBlobsFromNewBlobs(BLOCK_LIST *block_list, C_BLOB_LIST *new_blobs, C_BLOB_LIST *not_found_blobs)
void PrintSegmentationStats(BLOCK_LIST *block_list)
void ExtractBlobsFromSegmentation(BLOCK_LIST *blocks, C_BLOB_LIST *output_blob_list)
void print(FILE *fp, bool dump)
dump whole table
void rotate(const FCOORD &rotation)
BLOCK & operator=(const BLOCK &source)
void check_pitch()
check proportional
void reflect_polygon_in_y_axis()
void compute_row_margins()
PDBLK pdblk
Page Description Block.
bool prop() const
return proportional
void compress()
shrink white space
ROW_LIST * row_list()
get rows
int16_t kern() const
return kerning
void compress(const ICOORD vec)
shrink white space and move by vector
TBOX restricted_bounding_box(bool upper_dots, bool lower_dots) const
int16_t space() const
return spacing
void sort_rows()
decreasing y order
void set_lmargin(int16_t lmargin)
void move(const ICOORD vec)
void set_rmargin(int16_t rmargin)
void set_has_drop_cap(bool has)
float base_line(float xpos) const
TBOX bounding_box() const
POLY_BLOCK * poly_block() const
ICOORDELT_LIST rightside
right side vertices
POLY_BLOCK * hand_poly
weird as well
ICOORDELT_LIST leftside
left side vertices
void bounding_box(ICOORD &bottom_left, ICOORD &top_right) const
get box
void rotate(FCOORD rotation)
ICOORDELT_LIST * get_line(TDimension y)
TDimension height() const
void move(const ICOORD vec)
void move_bottom_edge(const TDimension y)
const ICOORD & botleft() const
TDimension bottom() const
WERD * ConstructWerdWithNewBlobs(C_BLOB_LIST *all_blobs, C_BLOB_LIST *orphan_blobs)
C_BLOB_LIST * rej_cblob_list()
C_BLOB_LIST * cblob_list()
void operator=(const ELIST_LINK &)