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;
50 cell_over_xheight_ = 2.0f;
51 pdblk.hand_poly =
nullptr;
52 left_it.set_to_list (&pdblk.leftside);
53 right_it.set_to_list (&pdblk.rightside);
55 left_it.add_to_end (
new ICOORDELT (xmin, ymin));
56 left_it.add_to_end (
new ICOORDELT (xmin, ymax));
57 right_it.add_to_end (
new ICOORDELT (xmax, ymin));
58 right_it.add_to_end (
new ICOORDELT (xmax, ymax));
67 static int decreasing_top_order(
const void *row1,
const void *row2) {
68 return (*reinterpret_cast<ROW* const*>(row2))->bounding_box().top() -
69 (*reinterpret_cast<ROW* const*>(row1))->bounding_box().top();
88 ROW_IT it(const_cast<ROW_LIST*>(&rows));
89 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
90 box += it.data()->restricted_bounding_box(upper_dots, lower_dots);
113 ROW_IT row_it(&rows);
115 row_it.sort (decreasing_top_order);
127 #define ROW_SPACING 5
129 ROW_IT row_it(&rows);
133 ICOORDELT_IT icoordelt_it;
139 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
140 row = row_it.data ();
197 tprintf (
"Proportional= %s\n", proportional ?
"TRUE" :
"FALSE");
198 tprintf (
"Kerning= %d\n", kerning);
199 tprintf (
"Spacing= %d\n", spacing);
200 tprintf (
"Fixed_pitch=%d\n", pitch);
204 tprintf (
"Left side coords are:\n");
205 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
206 tprintf (
"(%d,%d) ", it.data ()->x (), it.data ()->y ());
208 tprintf (
"Right side coords are:\n");
210 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
211 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;
233 re_rotation_ = source.re_rotation_;
234 classify_rotation_ = source.classify_rotation_;
235 skew_ = source.skew_;
249 static bool LeftMargin(ICOORDELT_LIST *segments,
int x,
int *margin) {
252 if (segments->empty())
254 ICOORDELT_IT seg_it(segments);
255 for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) {
256 int cur_margin = x - seg_it.data()->x();
257 if (cur_margin >= 0) {
259 *margin = cur_margin;
260 }
else if (cur_margin < *margin) {
261 *margin = cur_margin;
279 static bool RightMargin(ICOORDELT_LIST *segments,
int x,
int *margin) {
282 if (segments->empty())
284 ICOORDELT_IT seg_it(segments);
285 for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) {
286 int cur_margin = seg_it.data()->x() + seg_it.data()->y() - x;
287 if (cur_margin >= 0) {
289 *margin = cur_margin;
290 }
else if (cur_margin < *margin) {
291 *margin = cur_margin;
342 ROW *first_row = r_it.data();
343 ROW *second_row = r_it.data_relative(1);
351 WERD_IT werd_it(r_it.data()->word_list());
352 if (!werd_it.empty()) {
353 C_BLOB_IT cblob_it(werd_it.data()->cblob_list());
354 for (cblob_it.mark_cycle_pt(); !cblob_it.cycled_list();
355 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();
362 if (drop_cap_right < bbox.
right())
363 drop_cap_right = bbox.
right();
372 for (r_it.mark_cycle_pt(); !r_it.cycled_list(); r_it.forward()) {
373 ROW *row = r_it.data();
377 const std::unique_ptr< ICOORDELT_LIST> segments_left(
379 LeftMargin(segments_left.get(), row_box.
left(), &left_margin);
381 if (row_box.
top() >= drop_cap_bottom) {
382 int drop_cap_distance = row_box.
left() - row->
space() - drop_cap_right;
383 if (drop_cap_distance < 0)
384 drop_cap_distance = 0;
385 if (drop_cap_distance < left_margin)
386 left_margin = drop_cap_distance;
391 const std::unique_ptr< ICOORDELT_LIST> segments_right(
393 RightMargin(segments_right.get(), row_box.
right(), &right_margin);
410 BLOCK_IT block_it(block_list);
411 for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
412 BLOCK* block = block_it.data();
415 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
417 ROW* row = row_it.data();
420 for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
421 WERD* werd = werd_it.data();
427 tprintf(
"Block list stats:\nBlocks = %d\nRows = %d\nWords = %d\nBlobs = %d\n",
428 num_blocks, num_rows, num_words, num_blobs);
439 C_BLOB_LIST* output_blob_list) {
440 C_BLOB_IT return_list_it(output_blob_list);
441 BLOCK_IT block_it(blocks);
442 for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
443 BLOCK* block = block_it.data();
445 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
446 ROW* row = row_it.data();
449 for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
450 WERD* werd = werd_it.data();
451 return_list_it.move_to_last();
452 return_list_it.add_list_after(werd->
cblob_list());
453 return_list_it.move_to_last();
474 C_BLOB_LIST* new_blobs,
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();
485 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
486 ROW* row = row_it.data();
490 WERD_IT new_words_it(&new_words);
491 for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
492 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);