29 #include "config_auto.h"
32 #define MAXSPACING 128
46 inT16 block_space_gap_width;
48 inT16 block_non_space_gap_width;
49 BOOL8 old_text_ord_proportional;
52 block_it.set_to_list (blocks);
54 for (block_it.mark_cycle_pt (); !block_it.cycled_list ();
55 block_it.forward ()) {
56 block = block_it.data ();
57 gapmap =
new GAPMAP (block);
58 block_spacing_stats(block,
60 old_text_ord_proportional,
61 block_space_gap_width,
62 block_non_space_gap_width);
70 (
float) block_space_gap_width / block_non_space_gap_width < 3.0) {
71 block_non_space_gap_width = (
inT16) floor (block_space_gap_width / 3.0);
73 row_it.set_to_list (block->
get_rows ());
75 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
80 tprintf (
"Block %d Row %d: Now Proportional\n",
81 block_index, row_index);
82 row_spacing_stats(row,
86 block_space_gap_width,
87 block_non_space_gap_width);
92 (
"Block %d Row %d: Now Fixed Pitch Decision:%d fp flag:%f\n",
96 #ifndef GRAPHICS_DISABLED
112 void Textord::block_spacing_stats(
115 BOOL8 &old_text_ord_proportional,
116 inT16 &block_space_gap_width,
117 inT16 &block_non_space_gap_width
130 inT16 centre_to_centre;
132 float real_space_threshold;
133 float iqr_centre_to_centre;
134 float iqr_all_gap_stats;
138 row_it.set_to_list (block->
get_rows ());
139 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
140 row = row_it.data ();
146 blob_it.mark_cycle_pt ();
147 end_of_row = blob_it.data_relative (-1)->bounding_box ().right ();
151 blob_box = reduced_box_next (row, &blob_it);
154 row_length = end_of_row - blob_box.
left ();
155 if (blob_box.
width () < minwidth)
156 minwidth = blob_box.
width ();
157 prev_blob_box = blob_box;
158 while (!blob_it.cycled_list ()) {
162 blob_box = reduced_box_next (row, &blob_it);
165 if (blob_box.
width () < minwidth)
166 minwidth = blob_box.
width ();
167 gap_width = blob_box.
left () - prev_blob_box.
right ();
168 if (!ignore_big_gap (row, row_length, gapmap,
169 prev_blob_box.
right (), blob_box.
left ())) {
170 all_gap_stats.add (gap_width, 1);
172 centre_to_centre = (blob_box.
left () + blob_box.
right () -
173 (prev_blob_box.
left () +
174 prev_blob_box.
right ())) / 2;
176 centre_to_centre_stats.add (centre_to_centre, 1);
179 prev_blob_box = blob_box;
185 if (all_gap_stats.get_total () <= 1) {
186 block_non_space_gap_width = minwidth;
187 block_space_gap_width = -1;
189 old_text_ord_proportional =
TRUE;
193 iqr_centre_to_centre = centre_to_centre_stats.ile (0.75) -
194 centre_to_centre_stats.ile (0.25);
195 iqr_all_gap_stats = all_gap_stats.ile (0.75) - all_gap_stats.ile (0.25);
196 old_text_ord_proportional =
197 iqr_centre_to_centre * 2 > iqr_all_gap_stats;
209 block_non_space_gap_width = (
inT16) floor (all_gap_stats.median ());
212 row_it.set_to_list (block->
get_rows ());
213 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
214 row = row_it.data ();
219 real_space_threshold =
223 blob_it.mark_cycle_pt ();
225 blob_it.data_relative (-1)->bounding_box ().right ();
229 blob_box = reduced_box_next (row, &blob_it);
232 row_length = blob_box.
left () - end_of_row;
233 prev_blob_box = blob_box;
234 while (!blob_it.cycled_list ()) {
238 blob_box = reduced_box_next (row, &blob_it);
241 gap_width = blob_box.
left () - prev_blob_box.
right ();
242 if ((gap_width > real_space_threshold) &&
243 !ignore_big_gap (row, row_length, gapmap,
244 prev_blob_box.
right (),
259 || (!narrow_blob (row, prev_blob_box)
260 && !narrow_blob (row, blob_box))))
261 || (wide_blob (row, prev_blob_box)
262 && wide_blob (row, blob_box)))
263 space_gap_stats.add (gap_width, 1);
265 prev_blob_box = blob_box;
270 if (space_gap_stats.get_total () <= 2)
271 block_space_gap_width = -1;
273 block_space_gap_width =
274 MAX ((
inT16) floor (space_gap_stats.median ()),
275 3 * block_non_space_gap_width);
285 void Textord::row_spacing_stats(
290 inT16 block_space_gap_width,
291 inT16 block_non_space_gap_width
302 inT16 real_space_threshold = 0;
305 inT16 large_gap_count = 0;
306 BOOL8 suspected_table;
307 inT32 max_max_nonspace;
308 BOOL8 good_block_space_estimate = block_space_gap_width > 0;
310 inT32 row_length = 0;
312 inT32 sane_threshold;
316 if (!good_block_space_estimate)
317 block_space_gap_width =
inT16 (floor (row->
xheight / 2));
320 real_space_threshold =
321 block_non_space_gap_width +
324 block_non_space_gap_width)));
326 real_space_threshold =
327 (block_space_gap_width + block_non_space_gap_width) / 2;
329 blob_it.mark_cycle_pt ();
330 end_of_row = blob_it.data_relative (-1)->bounding_box ().right ();
334 blob_box = reduced_box_next (row, &blob_it);
337 row_length = end_of_row - blob_box.
left ();
338 prev_blob_box = blob_box;
339 while (!blob_it.cycled_list ()) {
343 blob_box = reduced_box_next (row, &blob_it);
346 gap_width = blob_box.
left () - prev_blob_box.
right ();
347 if (ignore_big_gap (row, row_length, gapmap,
348 prev_blob_box.
right (), blob_box.
left ()))
351 if (gap_width >= real_space_threshold) {
356 || (!narrow_blob (row, prev_blob_box)
357 && !narrow_blob (row, blob_box))))
358 || (wide_blob (row, prev_blob_box)
359 && wide_blob (row, blob_box)))
360 cert_space_gap_stats.add (gap_width, 1);
361 all_space_gap_stats.add (gap_width, 1);
364 small_gap_stats.add (gap_width, 1);
365 all_gap_stats.add (gap_width, 1);
367 prev_blob_box = blob_box;
370 suspected_table = (large_gap_count > 1) ||
371 ((large_gap_count > 0) &&
376 if ((cert_space_gap_stats.get_total () >=
380 cert_space_gap_stats.get_total () > 0)) {
383 &cert_space_gap_stats,
385 block_space_gap_width,
386 block_non_space_gap_width);
389 !isolated_row_stats (row, gapmap, &all_gap_stats, suspected_table,
390 block_idx, row_idx)) {
392 tprintf (
"B:%d R:%d -- Inadequate certain spaces.\n",
398 row->
kern_size = all_gap_stats.median ();
400 row->
kern_size = block_non_space_gap_width;
408 &all_space_gap_stats,
410 block_space_gap_width,
411 block_non_space_gap_width);
416 improve_row_threshold(row, &all_gap_stats);
421 if (suspected_table &&
424 tprintf (
"B:%d R:%d -- DONT BELIEVE SPACE %3.2f %d %3.2f.\n",
438 if (good_block_space_estimate &&
440 sane_space = block_space_gap_width;
447 (
"B:%d R:%d -- DONT BELIEVE SPACE %3.2f %d %3.2f -> %3.2f.\n",
460 tprintf (
"B:%d R:%d -- DONT BELIEVE THRESH %3.2f %d %3.2f->%d.\n",
469 if (suspected_table) {
472 sane_threshold =
inT32 (floor ((sane_space + row->
kern_size) / 2));
477 tprintf (
"B:%d R:%d -- SUSPECT NO SPACES %3.2f %d %3.2f.\n",
522 for (index = 0; index <= max_max_nonspace; index++) {
523 if (all_gap_stats.pile_count (index) > max)
524 max = all_gap_stats.pile_count (index);
526 (all_gap_stats.pile_count (index) < 0.1 * max)) {
570 (
"B:%d R:%d L:%d-- Kn:%d Sp:%d Thr:%d -- Kn:%3.2f (%d) Thr:%d (%d) Sp:%3.2f\n",
571 block_idx, row_idx, row_length, block_non_space_gap_width,
572 block_space_gap_width, real_space_threshold, row->
kern_size,
576 tprintf(
"row->kern_size = %3.2f, row->space_size = %3.2f, "
577 "row->space_threshold = %d\n",
581 void Textord::old_to_method(
583 STATS *all_gap_stats,
584 STATS *space_gap_stats,
585 STATS *small_gap_stats,
586 inT16 block_space_gap_width,
587 inT16 block_non_space_gap_width
595 if (row->
space_size > block_space_gap_width * 1.5) {
597 row->
space_size = block_space_gap_width * 1.5;
602 if (row->
space_size < (block_non_space_gap_width * 2) + 1)
603 row->
space_size = (block_non_space_gap_width * 2) + 1;
606 else if (space_gap_stats->
get_total () >= 1) {
609 if (row->
space_size > block_space_gap_width * 1.5) {
611 row->
space_size = block_space_gap_width * 1.5;
616 if (row->
space_size < (block_non_space_gap_width * 3) + 1)
617 row->
space_size = (block_non_space_gap_width * 3) + 1;
631 row->
kern_size = block_non_space_gap_width;
674 STATS *all_gap_stats,
675 BOOL8 suspected_table,
679 float crude_threshold_estimate;
680 inT16 small_gaps_count;
693 kern_estimate = all_gap_stats->
median ();
696 small_gaps_count = stats_count_under (all_gap_stats,
698 ceil (crude_threshold_estimate));
703 (total - small_gaps_count < 1)) {
705 tprintf (
"B:%d R:%d -- Cant do isolated row stats.\n",
710 blob_it.mark_cycle_pt ();
711 end_of_row = blob_it.data_relative (-1)->bounding_box ().right ();
715 blob_box = reduced_box_next (row, &blob_it);
718 row_length = end_of_row - blob_box.
left ();
719 prev_blob_box = blob_box;
720 while (!blob_it.cycled_list ()) {
724 blob_box = reduced_box_next (row, &blob_it);
727 gap_width = blob_box.
left () - prev_blob_box.
right ();
728 if (!ignore_big_gap (row, row_length, gapmap,
729 prev_blob_box.
right (), blob_box.
left ()) &&
730 (gap_width > crude_threshold_estimate)) {
734 (!narrow_blob (row, prev_blob_box) &&
735 !narrow_blob (row, blob_box)))) ||
736 (wide_blob (row, prev_blob_box) && wide_blob (row, blob_box)))
737 cert_space_gap_stats.add (gap_width, 1);
738 all_space_gap_stats.add (gap_width, 1);
740 if (gap_width < crude_threshold_estimate)
741 small_gap_stats.
add (gap_width, 1);
743 prev_blob_box = blob_box;
745 if (cert_space_gap_stats.get_total () >=
748 row->
space_size = cert_space_gap_stats.median ();
749 else if (suspected_table && (cert_space_gap_stats.get_total () > 0))
751 row->
space_size = cert_space_gap_stats.mean ();
753 else if (all_space_gap_stats.get_total () >=
756 row->
space_size = all_space_gap_stats.median ();
758 row->
space_size = all_space_gap_stats.mean ();
771 tprintf (
"B:%d R:%d -- Isolated row stats SANITY FAILURE: %f %d %f\n",
781 tprintf (
"B:%d R:%d -- Isolated row stats: %f %d %f\n",
791 for (index = 0; index < threshold; index++)
812 void Textord::improve_row_threshold(
TO_ROW *row,
STATS *all_gap_stats) {
815 inT16 reqd_zero_width = 0;
816 inT16 zero_width = 0;
817 inT16 zero_start = 0;
821 tprintf (
"Improve row threshold 0");
822 if ((all_gap_stats->
get_total () <= 25) ||
825 (stats_count_under (all_gap_stats,
826 (
inT16) ceil (kn + (sp - kn) / 3 + 0.5)) <
836 reqd_zero_width = (
inT16) floor ((sp - kn) / 3 + 0.5);
837 if (reqd_zero_width < 3)
840 for (index =
inT16 (ceil (kn)); index <
inT16 (floor (sp)); index++) {
847 if (zero_width >= reqd_zero_width)
856 tprintf (
" reqd_z_width: %d found %d 0's, starting %d; thresh: %d/n",
858 if ((zero_width < reqd_zero_width) ||
867 (
"Improve row kn:%5.2f sp:%5.2f 0's: %d -> %d thresh:%d -> %d\n",
874 (
"Improve row kn:%5.2f sp:%5.2f 0's: %d -> %d thresh:%d -> %d\n",
894 BOOL8 prev_fuzzy_non;
902 C_OUTLINE_IT cout_it;
904 C_BLOB_IT cblob_it = &cblobs;
910 float repetition_spacing;
925 inT16 word_count = 0;
927 rep_char_it.set_to_list (&(row->
rep_words));
928 if (!rep_char_it.empty ()) {
929 next_rep_char_word_right =
930 rep_char_it.data ()->bounding_box ().right ();
934 cblob_it.set_to_list (&cblobs);
936 word_it.set_to_list (&words);
939 prev_fuzzy_sp =
FALSE;
940 prev_fuzzy_non =
FALSE;
941 if (!box_it.empty ()) {
942 xstarts[0] = box_it.data ()->bounding_box ().left ();
943 if (xstarts[0] > next_rep_char_word_right) {
945 word = rep_char_it.extract ();
946 word_it.add_after_then_move (word);
956 repetition_spacing = find_mean_blob_spacing (word);
957 current_gap = box_it.data ()->bounding_box ().left () -
958 next_rep_char_word_right;
959 current_within_xht_gap = current_gap;
968 tprintf (
"Repch wd at BOL(%d, %d). rep spacing %5.2f; Rgap:%d ",
969 box_it.data ()->bounding_box ().left (),
970 box_it.data ()->bounding_box ().bottom (),
971 repetition_spacing, current_gap);
972 prev_fuzzy_sp =
FALSE;
973 prev_fuzzy_non =
FALSE;
974 if (rep_char_it.empty ()) {
978 rep_char_it.forward ();
979 next_rep_char_word_right =
980 rep_char_it.data ()->bounding_box ().right ();
984 peek_at_next_gap(row,
988 next_within_xht_gap);
990 bblob = box_it.data ();
994 cout_it.set_to_list (cblob_it.data ()->out_list ());
995 cout_it.move_to_last ();
997 delete bblob->
cblob ();
1001 cblob_it.add_after_then_move (bblob->
cblob ());
1002 prev_x = blob_box.
right ();
1005 bblob = box_it.data ();
1010 prev_gap = current_gap;
1011 prev_within_xht_gap = current_within_xht_gap;
1012 prev_blob_box = next_blob_box;
1013 current_gap = next_gap;
1014 current_within_xht_gap = next_within_xht_gap;
1015 peek_at_next_gap(row,
1019 next_within_xht_gap);
1021 inT16 prev_gap_arg = prev_gap;
1022 inT16 next_gap_arg = next_gap;
1024 prev_gap_arg = prev_within_xht_gap;
1025 next_gap_arg = next_within_xht_gap;
1028 if (blob_box.
left () > next_rep_char_word_right ||
1029 make_a_word_break(row, blob_box, prev_gap_arg, prev_blob_box,
1030 current_gap, current_within_xht_gap,
1031 next_blob_box, next_gap_arg,
1032 blanks, fuzzy_sp, fuzzy_non,
1033 prev_gap_was_a_space,
1034 break_at_next_gap) ||
1035 box_it.at_first()) {
1037 word =
new WERD (&cblobs, prev_blanks,
NULL);
1039 word_it.add_after_then_move (word);
1047 else if (prev_fuzzy_non)
1051 if (blob_box.
left () > next_rep_char_word_right) {
1053 word = rep_char_it.extract ();
1054 word_it.add_after_then_move (word);
1057 repetition_spacing = find_mean_blob_spacing (word);
1059 current_within_xht_gap = current_gap;
1070 (
"Repch wd (%d,%d) rep gap %5.2f; Lgap:%d (%d blanks);",
1073 repetition_spacing, current_gap, blanks);
1081 blob_box.
left () - next_rep_char_word_right;
1090 tprintf (
" Rgap:%d (%d blanks)\n",
1091 current_gap, blanks);
1095 if (rep_char_it.empty ()) {
1099 rep_char_it.forward ();
1100 next_rep_char_word_right =
1101 rep_char_it.data ()->bounding_box ().right ();
1105 if (box_it.at_first () && rep_char_it.empty ()) {
1108 xstarts[1] = prev_x;
1111 prev_blanks = blanks;
1112 prev_fuzzy_sp = fuzzy_sp;
1113 prev_fuzzy_non = fuzzy_non;
1118 while (!box_it.at_first ());
1121 while (!rep_char_it.empty ()) {
1122 word = rep_char_it.extract ();
1123 word_it.add_after_then_move (word);
1126 repetition_spacing = find_mean_blob_spacing (word);
1137 (
"Repch wd at EOL (%d,%d). rep spacing %d; Lgap:%d (%d blanks)\n",
1139 repetition_spacing, current_gap, blanks);
1145 if (rep_char_it.empty ()) {
1148 xstarts[1] = prev_x;
1151 rep_char_it.forward ();
1155 coeffs[1] = row->
line_m ();
1156 coeffs[2] = row->
line_c ();
1157 real_row =
new ROW (row,
1159 word_it.set_to_list (real_row->
word_list ());
1161 word_it.add_list_after (&words);
1165 tprintf (
"Row: Made %d words in row ((%d,%d)(%d,%d))\n",
1189 C_OUTLINE_IT cout_it;
1191 C_BLOB_IT cblob_it = &cblobs;
1199 inT16 word_count = 0;
1201 cblob_it.set_to_list(&cblobs);
1203 word_it.set_to_list(&words);
1205 if (!box_it.empty()) {
1208 bblob = box_it.data();
1212 cout_it.set_to_list(cblob_it.data()->out_list());
1213 cout_it.move_to_last();
1215 delete bblob->
cblob();
1219 cblob_it.add_after_then_move(bblob->
cblob());
1222 bblob = box_it.data();
1228 word_it.add_after_then_move(word);
1233 if (box_it.at_first()) {
1238 while (!box_it.at_first());
1241 coeffs[1] = row->
line_m();
1242 coeffs[2] = row->
line_c();
1244 word_it.set_to_list(real_row->
word_list());
1246 word_it.add_list_after(&words);
1249 tprintf (
"Row:Made %d words in row ((%d,%d)(%d,%d))\n",
1261 BOOL8 Textord::make_a_word_break(
1266 inT16 real_current_gap,
1267 inT16 within_xht_current_gap,
1273 BOOL8& prev_gap_was_a_space,
1274 BOOL8& break_at_next_gap) {
1277 float fuzzy_sp_to_kn_limit;
1279 if (break_at_next_gap) {
1280 break_at_next_gap =
FALSE;
1291 (real_current_gap < tosp_dont_fool_with_small_kerns * row->kern_size)))
1293 within_xht_current_gap = real_current_gap;
1296 current_gap = within_xht_current_gap;
1298 current_gap = real_current_gap;
1303 if (space && (current_gap <
MAX_INT16)) {
1304 if (current_gap < row->min_space) {
1329 prev_gap_was_a_space =
TRUE;
1350 (real_current_gap <= row->max_nonspace) &&
1354 #ifndef GRAPHICS_DISABLED
1355 mark_gap (blob_box, 20,
1356 prev_gap, prev_blob_box.
width (),
1357 current_gap, next_blob_box.
width (), next_gap);
1361 (real_current_gap <= row->space_threshold) &&
1368 #ifndef GRAPHICS_DISABLED
1369 mark_gap (blob_box, 21,
1370 prev_gap, prev_blob_box.
width (),
1371 current_gap, next_blob_box.
width (), next_gap);
1375 (real_current_gap < row->min_space) &&
1376 (within_xht_current_gap >= row->
min_space)) {
1378 #ifndef GRAPHICS_DISABLED
1379 mark_gap (blob_box, 22,
1380 prev_gap, prev_blob_box.
width (),
1381 current_gap, next_blob_box.
width (), next_gap);
1385 !suspected_punct_blob(row, prev_blob_box) &&
1386 suspected_punct_blob(row, blob_box)) {
1387 break_at_next_gap =
TRUE;
1390 else if ((current_gap < row->min_space) &&
1398 fuzzy_sp_to_kn_limit = 99999.0f;
1402 if ((prev_blob_box.
width () > 0) &&
1403 narrow_blob (row, prev_blob_box) &&
1404 prev_gap_was_a_space &&
1407 (current_gap > fuzzy_sp_to_kn_limit)) {
1415 #ifndef GRAPHICS_DISABLED
1416 mark_gap (blob_box, 1,
1417 prev_gap, prev_blob_box.
width (),
1418 current_gap, next_blob_box.
width (), next_gap);
1423 else if ((prev_blob_box.
width () > 0) &&
1424 narrow_blob (row, prev_blob_box) &&
1425 !prev_gap_was_a_space &&
1428 (current_gap > fuzzy_sp_to_kn_limit)) {
1436 #ifndef GRAPHICS_DISABLED
1437 mark_gap (blob_box, 2,
1438 prev_gap, prev_blob_box.
width (),
1439 current_gap, next_blob_box.
width (), next_gap);
1442 else if ((next_blob_box.
width () > 0) &&
1443 narrow_blob (row, next_blob_box) &&
1445 (current_gap <= tosp_gap_factor * next_gap)) {
1447 (current_gap > fuzzy_sp_to_kn_limit)) {
1455 #ifndef GRAPHICS_DISABLED
1456 mark_gap (blob_box, 3,
1457 prev_gap, prev_blob_box.
width (),
1458 current_gap, next_blob_box.
width (), next_gap);
1461 else if ((next_blob_box.
width () > 0) &&
1462 narrow_blob (row, next_blob_box) &&
1464 (current_gap * tosp_gap_factor <= next_gap)) {
1466 (current_gap > fuzzy_sp_to_kn_limit)) {
1474 #ifndef GRAPHICS_DISABLED
1475 mark_gap (blob_box, 4,
1476 prev_gap, prev_blob_box.
width (),
1477 current_gap, next_blob_box.
width (), next_gap);
1480 else if ((((next_blob_box.
width () > 0) &&
1481 narrow_blob (row, next_blob_box)) ||
1482 ((prev_blob_box.
width () > 0) &&
1483 narrow_blob (row, prev_blob_box)))) {
1485 #ifndef GRAPHICS_DISABLED
1486 mark_gap (blob_box, 6,
1487 prev_gap, prev_blob_box.
width (),
1488 current_gap, next_blob_box.
width (), next_gap);
1502 if ((prev_blob_box.
width () > 0) &&
1503 (next_blob_box.
width () > 0) &&
1506 wide_blob (row, prev_blob_box) &&
1507 wide_blob (row, next_blob_box)) {
1521 #ifndef GRAPHICS_DISABLED
1522 mark_gap (blob_box, 7,
1523 prev_gap, prev_blob_box.
width (),
1524 current_gap, next_blob_box.
width (), next_gap);
1526 }
else if (prev_blob_box.
width() > 0 &&
1527 next_blob_box.
width() > 0 &&
1531 !(narrow_blob(row, prev_blob_box) ||
1532 suspected_punct_blob(row, prev_blob_box)) &&
1533 !(narrow_blob(row, next_blob_box) ||
1534 suspected_punct_blob(row, next_blob_box))) {
1537 #ifndef GRAPHICS_DISABLED
1538 mark_gap (blob_box, 8,
1539 prev_gap, prev_blob_box.
width (),
1540 current_gap, next_blob_box.
width (), next_gap);
1544 (prev_blob_box.
width () > 0) &&
1545 (next_blob_box.
width () > 0) &&
1548 (!suspected_punct_blob (row, prev_blob_box) &&
1549 !suspected_punct_blob (row, next_blob_box)))) {
1552 #ifndef GRAPHICS_DISABLED
1553 mark_gap (blob_box, 9,
1554 prev_gap, prev_blob_box.
width (),
1555 current_gap, next_blob_box.
width (), next_gap);
1560 tprintf(
"word break = %d current_gap = %d, prev_gap = %d, "
1561 "next_gap = %d\n", space ? 1 : 0, current_gap,
1562 prev_gap, next_gap);
1563 prev_gap_was_a_space = space && !(fuzzy_non);
1571 (((
float) blob_box.
width () / blob_box.
height ()) <=
1581 (((
float) blob_box.
width () / blob_box.
height ()) >
1587 result = !narrow_blob (row, blob_box);
1594 float blob_x_centre;
1596 blob_x_centre = (box.
right () + box.
left ()) / 2.0;
1597 baseline = row->
baseline.
y (blob_x_centre);
1600 (box.
top () < baseline + row->
xheight / 2.0) ||
1606 void Textord::peek_at_next_gap(
TO_ROW *row,
1608 TBOX &next_blob_box,
1610 inT16 &next_within_xht_gap) {
1611 TBOX next_reduced_blob_box;
1613 BLOBNBOX_IT reduced_box_it = box_it;
1615 next_blob_box =
box_next (&box_it);
1616 next_reduced_blob_box = reduced_box_next (row, &reduced_box_it);
1617 if (box_it.at_first ()) {
1622 bit_beyond = box_it.data ()->bounding_box ();
1623 next_gap = bit_beyond.
left () - next_blob_box.
right ();
1624 bit_beyond = reduced_box_next (row, &reduced_box_it);
1625 next_within_xht_gap =
1626 bit_beyond.
left () - next_reduced_blob_box.
right ();
1631 #ifndef GRAPHICS_DISABLED
1632 void Textord::mark_gap(
1636 inT16 prev_blob_width,
1638 inT16 next_blob_width,
1694 blob.
left () - current_gap / 2.0f,
1699 tprintf (
" (%d,%d) Sp<->Kn Rule %d %d %d %d %d\n",
1700 blob.
left () - current_gap / 2, blob.
bottom (), rule,
1701 prev_gap, prev_blob_width, current_gap,
1702 next_blob_width, next_gap);
1706 float Textord::find_mean_blob_spacing(
WERD *word) {
1710 inT16 gap_count = 0;
1714 if (!cblob_it.empty ()) {
1715 cblob_it.mark_cycle_pt ();
1716 prev_right = cblob_it.data ()->bounding_box ().
right ();
1718 cblob_it.forward ();
1719 for (; !cblob_it.cycled_list (); cblob_it.forward ()) {
1720 blob_box = cblob_it.data ()->bounding_box ();
1721 gap_sum += blob_box.
left () - prev_right;
1723 prev_right = blob_box.
right ();
1727 return (gap_sum / (
float) gap_count);
1738 inT16 gap = right - left + 1;
1747 if ((gap > 2.1 * row->
xheight) && (row_length > 20 * row->
xheight))
1749 if ((gap > 1.75 * row->
xheight) &&
1750 ((row_length > 35 * row->
xheight) ||
1772 TBOX Textord::reduced_box_next(
1780 inT16 left_above_xht;
1781 inT16 new_left_above_xht;
1795 reduced_box = reduced_box_for_blob (blob, row, &left_above_xht);
1804 reduced_box_for_blob(blob, row, &new_left_above_xht);
1805 left_above_xht =
MIN (left_above_xht, new_left_above_xht);
1811 if ((reduced_box.
width () > 0) &&
1813 < left_above_xht) && (reduced_box.
height () > 0.7 * row->
xheight)) {
1814 #ifndef GRAPHICS_DISABLED
1820 reduced_box = full_box;
1846 TBOX Textord::reduced_box_for_blob(
1849 inT16 *left_above_xht) {
1851 float blob_x_centre;
1860 blob_x_centre = (blob_box.
left () + blob_box.
right ()) / 2.0;
1861 baseline = row->
baseline.
y (blob_x_centre);
1870 static_cast<float>(
MAX_INT16), left_limit, junk);
1871 if (left_limit > junk)
1874 *left_above_xht = (
inT16) floor (left_limit);
1884 if (left_limit > junk)
1892 (baseline + row->
xheight), junk, right_limit);
1893 if (junk > right_limit)
1897 ICOORD ((
inT16) ceil (right_limit), blob_box.top ()));