00001
00020 #include "mfcpch.h"
00021 #include "pagewalk.h"
00022
00023 #define EXTERN
00024
00027 EXTERN BOOL_VAR (current_word_quit, FALSE, "Stop processing this word");
00028 DLLSYM BOOL_VAR (selection_quit, FALSE, "Stop processing this selection");
00036 BOX block_list_bounding_box(
00037 BLOCK_LIST *block_list
00038 ) {
00039 BLOCK_IT block_it(block_list);
00040 BOX enclosing_box;
00041
00042 for (block_it.mark_cycle_pt (); !block_it.cycled_list ();
00043 block_it.forward ())
00044 enclosing_box += block_it.data ()->bounding_box ();
00045 return enclosing_box;
00046 }
00047
00048
00062 const BOX block_list_compress(
00063 BLOCK_LIST *block_list) {
00064 BLOCK_IT block_it(block_list);
00065 BLOCK *block;
00066 ICOORD initial_top_left;
00067 ICOORD block_spacing (0, BLOCK_SPACING);
00068 BOX enclosing_box;
00069
00070 initial_top_left = block_it.data ()->bounding_box ().topleft ();
00071
00072 block_it.sort (block_name_order);
00073
00074
00075
00076
00077 enclosing_box = BOX (initial_top_left, initial_top_left);
00078 enclosing_box.move_bottom_edge (BLOCK_SPACING);
00079
00080 for (block_it.mark_cycle_pt ();
00081 !block_it.cycled_list (); block_it.forward ()) {
00082 block = block_it.data ();
00083 block->compress (enclosing_box.botleft () - block_spacing -
00084 block->bounding_box ().topleft ());
00085 enclosing_box += block->bounding_box ();
00086 }
00087 return enclosing_box;
00088 }
00089
00090
00094 void block_list_move(
00095 BLOCK_LIST *block_list,
00096 ICOORD vec
00097 ) {
00098 BLOCK_IT block_it(block_list);
00099
00100 for (block_it.mark_cycle_pt (); !block_it.cycled_list ();
00101 block_it.forward ())
00102 block_it.data ()->move (vec);
00103 }
00104
00105
00113 int block_name_order(
00114 const void *block1p,
00115 const void *block2p
00116 ) {
00117 int result;
00118 BLOCK *block1 = *(BLOCK **) block1p;
00119 BLOCK *block2 = *(BLOCK **) block2p;
00120
00121 result = strcmp (block1->name (), block2->name ());
00122 if (result == 0)
00123 result = block2->bounding_box ().top () - block1->bounding_box ().top ();
00124 return result;
00125 }
00126
00127
00134 void
00135 process_all_blobs (
00136 BLOCK_LIST * block_list,
00137 BOOL8 blob_processor (
00138 BLOCK *, ROW *, WERD *, PBLOB *),
00139 BOOL8 c_blob_processor (
00140 BLOCK *, ROW *, WERD *, C_BLOB *)
00141 ) {
00142 BLOCK_IT block_it(block_list);
00143 BLOCK *block;
00144 ROW_IT row_it;
00145 ROW *row;
00146 WERD_IT word_it;
00147 WERD *word;
00148 PBLOB_IT blob_it;
00149 PBLOB *blob;
00150 C_BLOB_IT c_blob_it;
00151 C_BLOB *c_blob;
00152
00153 for (block_it.mark_cycle_pt ();
00154 !block_it.cycled_list (); block_it.forward ()) {
00155 block = block_it.data ();
00156 row_it.set_to_list (block->row_list ());
00157 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
00158 row = row_it.data ();
00159 word_it.set_to_list (row->word_list ());
00160 for (word_it.mark_cycle_pt ();
00161 !word_it.cycled_list (); word_it.forward ()) {
00162 word = word_it.data ();
00163 if (word->flag (W_POLYGON)) {
00164 if (blob_processor != NULL) {
00165 blob_it.set_to_list (word->blob_list ());
00166 for (blob_it.mark_cycle_pt ();
00167 !blob_it.cycled_list (); blob_it.forward ()) {
00168 blob = blob_it.data ();
00169 if (!blob_processor (block, row, word, blob) ||
00170 selection_quit)
00171 return;
00172 }
00173 }
00174 }
00175 else {
00176 if (c_blob_processor != NULL) {
00177 c_blob_it.set_to_list (word->cblob_list ());
00178 for (c_blob_it.mark_cycle_pt ();
00179 !c_blob_it.cycled_list (); c_blob_it.forward ()) {
00180 c_blob = c_blob_it.data ();
00181 if (!c_blob_processor (block, row, word, c_blob) ||
00182 selection_quit)
00183 return;
00184 }
00185 }
00186 }
00187 }
00188 }
00189 }
00190 }
00191
00192
00199 void
00200 process_selected_blobs (
00201 BLOCK_LIST * block_list,
00202 BOX & selection_box,
00203 BOOL8 blob_processor (
00204 BLOCK *, ROW *, WERD *, PBLOB *),
00205 BOOL8 c_blob_processor (
00206 BLOCK *, ROW *, WERD *, C_BLOB *)
00207 ) {
00208 BLOCK_IT block_it(block_list);
00209 BLOCK *block;
00210 ROW_IT row_it;
00211 ROW *row;
00212 WERD_IT word_it;
00213 WERD *word;
00214 PBLOB_IT blob_it;
00215 PBLOB *blob;
00216 C_BLOB_IT c_blob_it;
00217 C_BLOB *c_blob;
00218
00219 for (block_it.mark_cycle_pt ();
00220 !block_it.cycled_list (); block_it.forward ()) {
00221 block = block_it.data ();
00222 if (block->bounding_box ().overlap (selection_box)) {
00223 row_it.set_to_list (block->row_list ());
00224 for (row_it.mark_cycle_pt ();
00225 !row_it.cycled_list (); row_it.forward ()) {
00226 row = row_it.data ();
00227 if (row->bounding_box ().overlap (selection_box)) {
00228 word_it.set_to_list (row->word_list ());
00229 for (word_it.mark_cycle_pt ();
00230 !word_it.cycled_list (); word_it.forward ()) {
00231 word = word_it.data ();
00232 if (word->bounding_box ().overlap (selection_box)) {
00233 if (word->flag (W_POLYGON)) {
00234 if (blob_processor != NULL) {
00235 blob_it.set_to_list (word->blob_list ());
00236 for (blob_it.mark_cycle_pt ();
00237 !blob_it.cycled_list ();
00238 blob_it.forward ()) {
00239 blob = blob_it.data ();
00240 if (blob->bounding_box ().
00241 overlap (selection_box)) {
00242 if (!blob_processor
00243 (block, row, word, blob)
00244 || selection_quit)
00245 return;
00246 }
00247 }
00248 }
00249 }
00250 else {
00251 if (c_blob_processor != NULL) {
00252 c_blob_it.set_to_list (word->cblob_list ());
00253 for (c_blob_it.mark_cycle_pt ();
00254 !c_blob_it.cycled_list ();
00255 c_blob_it.forward ()) {
00256 c_blob = c_blob_it.data ();
00257 if (c_blob->
00258 bounding_box ().
00259 overlap (selection_box)) {
00260 if (!c_blob_processor
00261 (block, row, word, c_blob)
00262 || selection_quit)
00263 return;
00264 }
00265 }
00266 }
00267 }
00268 }
00269 }
00270 }
00271 }
00272 }
00273 }
00274 }
00275
00276
00283 void
00284 process_all_words (
00285 BLOCK_LIST * block_list,
00286 BOOL8 word_processor (
00287 BLOCK *, ROW *, WERD *)) {
00288 BLOCK_IT block_it(block_list);
00289 BLOCK *block;
00290 ROW_IT row_it;
00291 ROW *row;
00292 WERD_IT word_it;
00293 WERD *word;
00294
00295 for (block_it.mark_cycle_pt ();
00296 !block_it.cycled_list (); block_it.forward ()) {
00297 block = block_it.data ();
00298 row_it.set_to_list (block->row_list ());
00299 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
00300 row = row_it.data ();
00301 word_it.set_to_list (row->word_list ());
00302 for (word_it.mark_cycle_pt ();
00303 !word_it.cycled_list (); word_it.forward ()) {
00304 word = word_it.data ();
00305 if (!word_processor (block, row, word) || selection_quit)
00306 return;
00307 }
00308 }
00309 }
00310 }
00311
00312
00319 void
00320 process_selected_words (
00321 BLOCK_LIST * block_list,
00322
00323 BOX & selection_box, BOOL8 word_processor (
00324 BLOCK *,
00325 ROW *,
00326 WERD *)) {
00327 BLOCK_IT block_it(block_list);
00328 BLOCK *block;
00329 ROW_IT row_it;
00330 ROW *row;
00331 WERD_IT word_it;
00332 WERD *word;
00333
00334 for (block_it.mark_cycle_pt ();
00335 !block_it.cycled_list (); block_it.forward ()) {
00336 block = block_it.data ();
00337 if (block->bounding_box ().overlap (selection_box)) {
00338 row_it.set_to_list (block->row_list ());
00339 for (row_it.mark_cycle_pt ();
00340 !row_it.cycled_list (); row_it.forward ()) {
00341 row = row_it.data ();
00342 if (row->bounding_box ().overlap (selection_box)) {
00343 word_it.set_to_list (row->word_list ());
00344 for (word_it.mark_cycle_pt ();
00345 !word_it.cycled_list (); word_it.forward ()) {
00346 word = word_it.data ();
00347 if (word->bounding_box ().overlap (selection_box)) {
00348 if (!word_processor (block, row, word) ||
00349 selection_quit)
00350 return;
00351 }
00352 }
00353 }
00354 }
00355 }
00356 }
00357 }
00358
00359
00366 void
00367 process_all_words_it (
00368 BLOCK_LIST * block_list,
00369 BOOL8 word_processor (
00370 BLOCK *,
00371 ROW *,
00372 WERD *,
00373 BLOCK_IT &,
00374 ROW_IT &, WERD_IT &)) {
00375 BLOCK_IT block_it(block_list);
00376 BLOCK *block;
00377 ROW_IT row_it;
00378 ROW *row;
00379 WERD_IT word_it;
00380 WERD *word;
00381
00382 for (block_it.mark_cycle_pt ();
00383 !block_it.cycled_list (); block_it.forward ()) {
00384 block = block_it.data ();
00385 row_it.set_to_list (block->row_list ());
00386 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
00387 row = row_it.data ();
00388 word_it.set_to_list (row->word_list ());
00389 for (word_it.mark_cycle_pt ();
00390 !word_it.cycled_list (); word_it.forward ()) {
00391 word = word_it.data ();
00392 if (!word_processor
00393 (block, row, word, block_it, row_it, word_it)
00394 || selection_quit)
00395 return;
00396 }
00397 }
00398 }
00399 }
00400
00401
00408 void
00409 process_selected_words_it (
00410 BLOCK_LIST * block_list,
00411 BOX & selection_box,
00412 BOOL8 word_processor (
00413 BLOCK *, ROW *, WERD *, BLOCK_IT &, ROW_IT &, WERD_IT &)
00414 ) {
00415 BLOCK_IT block_it(block_list);
00416 BLOCK *block;
00417 ROW_IT row_it;
00418 ROW *row;
00419 WERD_IT word_it;
00420 WERD *word;
00421
00422 for (block_it.mark_cycle_pt ();
00423 !block_it.cycled_list (); block_it.forward ()) {
00424 block = block_it.data ();
00425 if (block->bounding_box ().overlap (selection_box)) {
00426 row_it.set_to_list (block->row_list ());
00427 for (row_it.mark_cycle_pt ();
00428 !row_it.cycled_list (); row_it.forward ()) {
00429 row = row_it.data ();
00430 if (row->bounding_box ().overlap (selection_box)) {
00431 word_it.set_to_list (row->word_list ());
00432 for (word_it.mark_cycle_pt ();
00433 !word_it.cycled_list (); word_it.forward ()) {
00434 word = word_it.data ();
00435 if (word->bounding_box ().overlap (selection_box)) {
00436 if (!word_processor (block, row, word,
00437 block_it, row_it, word_it) ||
00438 selection_quit)
00439 return;
00440 }
00441 }
00442 }
00443 }
00444 }
00445 }
00446 }
00447
00448
00455 void
00456 process_all_blocks (
00457 BLOCK_LIST * block_list,
00458 BOOL8 block_processor (
00459 BLOCK *)) {
00460 BLOCK_IT block_it(block_list);
00461 BLOCK *block;
00462
00463 for (block_it.mark_cycle_pt ();
00464 !block_it.cycled_list (); block_it.forward ()) {
00465 block = block_it.data ();
00466 if (!block_processor (block) || selection_quit)
00467 return;
00468 }
00469 }
00470
00471
00478 void
00479 process_selected_blocks (
00480 BLOCK_LIST * block_list,
00481 BOX & selection_box,
00482 BOOL8 block_processor (BLOCK *)
00483 ) {
00484 BLOCK_IT block_it(block_list);
00485 BLOCK *block;
00486
00487 for (block_it.mark_cycle_pt ();
00488 !block_it.cycled_list (); block_it.forward ()) {
00489 block = block_it.data ();
00490 if (block->bounding_box ().overlap (selection_box)) {
00491 if (!block_processor (block) || selection_quit)
00492 return;
00493 }
00494 }
00495 }
00496
00497
00504 void
00505 process_all_rows (
00506 BLOCK_LIST * block_list,
00507 BOOL8 row_processor (
00508 BLOCK *, ROW *)) {
00509 BLOCK_IT block_it(block_list);
00510 BLOCK *block;
00511 ROW_IT row_it;
00512 ROW *row;
00513
00514 for (block_it.mark_cycle_pt ();
00515 !block_it.cycled_list (); block_it.forward ()) {
00516 block = block_it.data ();
00517 row_it.set_to_list (block->row_list ());
00518 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
00519 row = row_it.data ();
00520 if (!row_processor (block, row) || selection_quit)
00521 return;
00522 }
00523 }
00524 }
00525
00526
00533 void
00534 process_selected_rows (
00535 BLOCK_LIST * block_list,
00536
00537 BOX & selection_box, BOOL8 row_processor (
00538 BLOCK *,
00539 ROW *)) {
00540 BLOCK_IT block_it(block_list);
00541 BLOCK *block;
00542 ROW_IT row_it;
00543 ROW *row;
00544
00545 for (block_it.mark_cycle_pt ();
00546 !block_it.cycled_list (); block_it.forward ()) {
00547 block = block_it.data ();
00548 if (block->bounding_box ().overlap (selection_box)) {
00549 row_it.set_to_list (block->row_list ());
00550 for (row_it.mark_cycle_pt ();
00551 !row_it.cycled_list (); row_it.forward ()) {
00552 row = row_it.data ();
00553 if (row->bounding_box ().overlap (selection_box)) {
00554 if (!row_processor (block, row) || selection_quit)
00555 return;
00556 }
00557 }
00558 }
00559 }
00560 }
00561
00562
00569 void
00570 process_all_rows_it (
00571 BLOCK_LIST * block_list,
00572 BOOL8 row_processor (
00573 BLOCK *,
00574 ROW *, BLOCK_IT &, ROW_IT &)) {
00575 BLOCK_IT block_it(block_list);
00576 BLOCK *block;
00577 ROW_IT row_it;
00578 ROW *row;
00579
00580 for (block_it.mark_cycle_pt ();
00581 !block_it.cycled_list (); block_it.forward ()) {
00582 block = block_it.data ();
00583 row_it.set_to_list (block->row_list ());
00584 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
00585 row = row_it.data ();
00586 if (!row_processor (block, row, block_it, row_it) || selection_quit)
00587 return;
00588 }
00589 }
00590 }
00591
00592
00599 void
00600 process_selected_rows_it (
00601 BLOCK_LIST * block_list,
00602
00603 BOX & selection_box,
00604 BOOL8 row_processor (BLOCK *,ROW *,BLOCK_IT &,ROW_IT &)
00605 ) {
00606 BLOCK_IT block_it(block_list);
00607 BLOCK *block;
00608 ROW_IT row_it;
00609 ROW *row;
00610
00611 for (block_it.mark_cycle_pt ();
00612 !block_it.cycled_list (); block_it.forward ()) {
00613 block = block_it.data ();
00614 if (block->bounding_box ().overlap (selection_box)) {
00615 row_it.set_to_list (block->row_list ());
00616 for (row_it.mark_cycle_pt ();
00617 !row_it.cycled_list (); row_it.forward ()) {
00618 row = row_it.data ();
00619 if (row->bounding_box ().overlap (selection_box)) {
00620 if (!row_processor (block, row, block_it, row_it) ||
00621 selection_quit)
00622 return;
00623 }
00624 }
00625 }
00626 }
00627 }