00001
00020 #include "mfcpch.h"
00021 #include "tfacep.h"
00022 #include "tstruct.h"
00023
00024
00025 static ERRCODE BADFRAGMENTS = "Couldn't find matching fragment ends";
00026
00027 ELISTIZE (FRAGMENT)
00028
00032 FRAGMENT::FRAGMENT (
00033 EDGEPT * head_pt,
00034 EDGEPT * tail_pt
00035 ):head (head_pt->pos.x, head_pt->pos.y), tail (tail_pt->pos.x,
00036 tail_pt->pos.y) {
00037 headpt = head_pt;
00038 tailpt = tail_pt;
00039 }
00040
00041
00045 WERD *make_ed_word(
00046 TWERD *tessword,
00047 WERD *clone
00048 ) {
00049 WERD *word;
00050 TBLOB *tblob;
00051 PBLOB *blob;
00052 PBLOB_LIST blobs;
00053 PBLOB_IT blob_it = &blobs;
00054
00055 for (tblob = tessword->blobs; tblob != NULL; tblob = tblob->next) {
00056 blob = make_ed_blob (tblob);
00057 if (blob != NULL)
00058 blob_it.add_after_then_move (blob);
00059 }
00060 if (!blobs.empty ())
00061 word = new WERD (&blobs, clone);
00062 else
00063 word = NULL;
00064 return word;
00065 }
00066
00067
00071 PBLOB *make_ed_blob(
00072 TBLOB *tessblob
00073 ) {
00074 TESSLINE *tessol;
00075 FRAGMENT_LIST fragments;
00076 OUTLINE *outline;
00077 OUTLINE_LIST out_list;
00078 OUTLINE_IT out_it = &out_list;
00079
00080 for (tessol = tessblob->outlines; tessol != NULL; tessol = tessol->next) {
00081
00082 register_outline(tessol, &fragments);
00083 }
00084 while (!fragments.empty ()) {
00085 outline = make_ed_outline (&fragments);
00086 if (outline != NULL)
00087 out_it.add_after_then_move (outline);
00088 }
00089 if (out_it.empty())
00090 return NULL;
00091 return new PBLOB (&out_list);
00092 }
00093
00094
00098 OUTLINE *make_ed_outline(
00099 FRAGMENT_LIST *list
00100 ) {
00101 FRAGMENT *fragment;
00102 EDGEPT *edgept;
00103 ICOORD headpos;
00104 ICOORD tailpos;
00105 FCOORD pos;
00106 FCOORD vec;
00107 POLYPT *polypt;
00108 POLYPT_LIST poly_list;
00109 POLYPT_IT poly_it = &poly_list;
00110 FRAGMENT_IT fragment_it = list;
00111
00112 headpos = fragment_it.data ()->head;
00113 do {
00114 fragment = fragment_it.data ();
00115 edgept = fragment->headpt;
00116 do {
00117 pos = FCOORD (edgept->pos.x, edgept->pos.y);
00118 vec = FCOORD (edgept->vec.x, edgept->vec.y);
00119 polypt = new POLYPT (pos, vec);
00120
00121 poly_it.add_after_then_move (polypt);
00122 edgept = edgept->next;
00123 }
00124 while (edgept != fragment->tailpt);
00125 tailpos = ICOORD (edgept->pos.x, edgept->pos.y);
00126
00127 delete fragment_it.extract ();
00128 if (tailpos != headpos) {
00129 if (fragment_it.empty ()) {
00130
00131
00132
00133 return NULL;
00134 }
00135 fragment_it.forward ();
00136
00137 for (fragment_it.mark_cycle_pt (); !fragment_it.cycled_list () && fragment_it.data ()->head != tailpos;
00138 fragment_it.forward ());
00139 if (fragment_it.data ()->head != tailpos) {
00140
00141
00142 for (fragment_it.mark_cycle_pt ();
00143 !fragment_it.cycled_list (); fragment_it.forward ()) {
00144 fragment = fragment_it.extract ();
00145
00146
00147
00148 delete fragment;
00149 }
00150 return NULL;
00151
00152 }
00153 }
00154 }
00155 while (tailpos != headpos);
00156 return new OUTLINE (&poly_it);
00157 }
00158
00159
00163 void register_outline(
00164 TESSLINE *outline,
00165 FRAGMENT_LIST *list
00166 ) {
00167 EDGEPT *startpt;
00168 EDGEPT *headpt;
00169 EDGEPT *tailpt;
00170 FRAGMENT *fragment;
00171 FRAGMENT_IT it = list;
00172
00173 startpt = outline->loop;
00174 do {
00175 startpt = startpt->next;
00176 if (startpt == NULL)
00177 return;
00178 }
00179 while (startpt->flags[0] == 0 && startpt != outline->loop);
00180 headpt = startpt;
00181 do
00182 startpt = startpt->next;
00183 while (startpt->flags[0] != 0 && startpt != headpt);
00184 if (startpt->flags[0] != 0)
00185 return;
00186
00187 headpt = startpt;
00188 do {
00189 tailpt = headpt;
00190 do
00191 tailpt = tailpt->next;
00192 while (tailpt->flags[0] == 0 && tailpt != startpt);
00193 fragment = new FRAGMENT (headpt, tailpt);
00194 it.add_after_then_move (fragment);
00195 while (tailpt->flags[0] != 0)
00196 tailpt = tailpt->next;
00197 headpt = tailpt;
00198 }
00199 while (tailpt != startpt);
00200 }
00201
00202
00206 void convert_choice_lists(
00207 ARRAY tessarray,
00208 BLOB_CHOICE_LIST_CLIST *ratings
00209 ) {
00210 INT32 length;
00211 INT32 index;
00212 LIST result;
00213
00214 BLOB_CHOICE_LIST_C_IT it = ratings;
00215 BLOB_CHOICE_LIST *choice;
00216
00217 if (tessarray != NULL) {
00218 length = array_count (tessarray);
00219 for (index = 0; index < length; index++) {
00220 result = (LIST) array_value (tessarray, index);
00221
00222 choice = new BLOB_CHOICE_LIST;
00223
00224 convert_choice_list(result, *choice);
00225
00226 it.add_after_then_move (choice);
00227 }
00228 free_mem(tessarray);
00229 }
00230 }
00231
00232
00236 void convert_choice_list(
00237 LIST list,
00238 BLOB_CHOICE_LIST &ratings
00239 ) {
00240 LIST result;
00241 BLOB_CHOICE_IT it = &ratings;
00242 BLOB_CHOICE *choice;
00243 A_CHOICE *tesschoice;
00244
00245 for (result = list; result != NULL; result = result->next) {
00246
00247 tesschoice = (A_CHOICE *) result->node;
00248
00249 choice = new BLOB_CHOICE (tesschoice->string[0], tesschoice->rating,
00250 tesschoice->certainty, tesschoice->config);
00251 it.add_after_then_move (choice);
00252 }
00253 destroy_nodes (list, (void (*)(void *)) free_choice);
00254
00255 }
00256
00257
00261 void make_tess_row(
00262 DENORM *denorm,
00263 TEXTROW *tessrow
00264 ) {
00265 tessrow->baseline.segments = 1;
00266 tessrow->baseline.xstarts[0] = -32767;
00267 tessrow->baseline.xstarts[1] = 32767;
00268 tessrow->baseline.quads[0].a = 0;
00269 tessrow->baseline.quads[0].b = 0;
00270 tessrow->baseline.quads[0].c = bln_baseline_offset;
00271 tessrow->xheight.segments = 1;
00272 tessrow->xheight.xstarts[0] = -32767;
00273 tessrow->xheight.xstarts[1] = 32767;
00274 tessrow->xheight.quads[0].a = 0;
00275 tessrow->xheight.quads[0].b = 0;
00276 tessrow->xheight.quads[0].c = bln_x_height + bln_baseline_offset;
00277 tessrow->lineheight = bln_x_height;
00278 tessrow->ascrise = denorm->row ()->ascenders () * denorm->scale ();
00279 tessrow->descdrop = denorm->row ()->descenders () * denorm->scale ();
00280 }
00281
00282
00286 TWERD *make_tess_word(
00287 WERD *word,
00288 TEXTROW *row
00289 ) {
00290 TWERD *tessword;
00291
00292 tessword = newword ();
00293 tessword->row = row;
00294
00295 tessword->correct = strsave (word->text ());
00296 tessword->guess = NULL;
00297 tessword->blobs = make_tess_blobs (word->blob_list ());
00298 tessword->blanks = 1;
00299 tessword->blobcount = word->blob_list ()->length ();
00300 tessword->next = NULL;
00301 return tessword;
00302 }
00303
00304
00308 TBLOB *make_tess_blobs(
00309 PBLOB_LIST *bloblist
00310 ) {
00311 PBLOB_IT it = bloblist;
00312 PBLOB *blob;
00313 TBLOB *head;
00314 TBLOB *tail;
00315 TBLOB *tessblob;
00316
00317 head = NULL;
00318 tail = NULL;
00319 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00320 blob = it.data ();
00321 tessblob = make_tess_blob (blob, TRUE);
00322 if (head)
00323 tail->next = tessblob;
00324 else
00325 head = tessblob;
00326 tail = tessblob;
00327 }
00328 return head;
00329 }
00330
00331
00335 TBLOB *make_tess_blob(
00336 PBLOB *blob,
00337 BOOL8 flatten
00338 ) {
00339 INT32 index;
00340 TBLOB *tessblob;
00341
00342 tessblob = newblob ();
00343 tessblob->outlines = (struct olinestruct *)
00344 make_tess_outlines (blob->out_list (), flatten);
00345 for (index = 0; index < TBLOBFLAGS; index++)
00346 tessblob->flags[index] = 0;
00347 tessblob->correct = 0;
00348 tessblob->guess = 0;
00349 for (index = 0; index < MAX_WO_CLASSES; index++) {
00350 tessblob->classes[index] = 0;
00351 tessblob->values[index] = 0;
00352 }
00353 tessblob->next = NULL;
00354 return tessblob;
00355 }
00356
00357
00361 TESSLINE *make_tess_outlines(
00362 OUTLINE_LIST *outlinelist,
00363 BOOL8 flatten
00364 ) {
00365 OUTLINE_IT it = outlinelist;
00366 OUTLINE *outline;
00367 TESSLINE *head;
00368 TESSLINE *tail;
00369 TESSLINE *tessoutline;
00370
00371 head = NULL;
00372 tail = NULL;
00373 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00374 outline = it.data ();
00375 tessoutline = newoutline ();
00376 tessoutline->compactloop = NULL;
00377 tessoutline->loop = make_tess_edgepts (outline->polypts (),
00378 tessoutline->topleft,
00379 tessoutline->botright);
00380 if (tessoutline->loop == NULL) {
00381 oldoutline(tessoutline);
00382 continue;
00383 }
00384 tessoutline->start = tessoutline->loop->pos;
00385 tessoutline->node = NULL;
00386 tessoutline->next = NULL;
00387 tessoutline->child = NULL;
00388 if (!outline->child ()->empty ()) {
00389 if (flatten)
00390 tessoutline->next = (struct olinestruct *)
00391 make_tess_outlines (outline->child (), flatten);
00392 else {
00393 tessoutline->next = NULL;
00394 tessoutline->child = (struct olinestruct *)
00395 make_tess_outlines (outline->child (), flatten);
00396 }
00397 }
00398 else
00399 tessoutline->next = NULL;
00400 if (head)
00401 tail->next = tessoutline;
00402 else
00403 head = tessoutline;
00404 while (tessoutline->next != NULL)
00405 tessoutline = tessoutline->next;
00406 tail = tessoutline;
00407 }
00408 return head;
00409 }
00410
00411
00415 EDGEPT *make_tess_edgepts(
00416 POLYPT_LIST *edgeptlist,
00417 TPOINT &tl,
00418 TPOINT &br) {
00419 INT32 index;
00420 POLYPT_IT it = edgeptlist;
00421 POLYPT *edgept;
00422 EDGEPT *head;
00423 EDGEPT *tail;
00424 EDGEPT *tessedgept;
00425
00426 head = NULL;
00427 tail = NULL;
00428 tl.x = MAX_INT16;
00429 tl.y = -MAX_INT16;
00430 br.x = -MAX_INT16;
00431 br.y = MAX_INT16;
00432 for (it.mark_cycle_pt (); !it.cycled_list ();) {
00433 edgept = it.data ();
00434 tessedgept = newedgept ();
00435 tessedgept->pos.x = (INT16) edgept->pos.x ();
00436 tessedgept->pos.y = (INT16) edgept->pos.y ();
00437 if (tessedgept->pos.x < tl.x)
00438 tl.x = tessedgept->pos.x;
00439 if (tessedgept->pos.x > br.x)
00440 br.x = tessedgept->pos.x;
00441 if (tessedgept->pos.y > tl.y)
00442 tl.y = tessedgept->pos.y;
00443 if (tessedgept->pos.y < br.y)
00444 br.y = tessedgept->pos.y;
00445 if (head != NULL && tessedgept->pos.x == tail->pos.x
00446 && tessedgept->pos.y == tail->pos.y) {
00447 oldedgept(tessedgept);
00448 }
00449 else {
00450 for (index = 0; index < EDGEPTFLAGS; index++)
00451 tessedgept->flags[index] = 0;
00452 if (head != NULL) {
00453 tail->vec.x = tessedgept->pos.x - tail->pos.x;
00454 tail->vec.y = tessedgept->pos.y - tail->pos.y;
00455 tessedgept->prev = tail;
00456 }
00457 tessedgept->next = head;
00458 if (head)
00459 tail->next = tessedgept;
00460 else
00461 head = tessedgept;
00462 tail = tessedgept;
00463 }
00464 it.forward ();
00465 }
00466 head->prev = tail;
00467 tail->vec.x = head->pos.x - tail->pos.x;
00468 tail->vec.y = head->pos.y - tail->pos.y;
00469 if (head == tail) {
00470 oldedgept(head);
00471 return NULL;
00472 }
00473 return head;
00474 }