00001
00020 #include "mfcpch.h"
00021 #include "varable.h"
00022 #include "ocrrow.h"
00023 #include "polyblob.h"
00024
00025 #include "polyaprx.h"
00026
00027 #define EXTERN
00028
00031 EXTERN BOOL_VAR (polygon_tess_approximation, TRUE,
00032 "Do tess poly instead of greyscale");
00035 ELISTIZE_S (PBLOB)
00036
00037
00043 static void position_outline(
00044 OUTLINE *outline,
00045 OUTLINE_LIST *destlist
00046 ) {
00047 OUTLINE *dest_outline;
00048 OUTLINE_IT it = destlist;
00049
00050 OUTLINE_IT child_it = outline->child ();
00051
00052 if (!it.empty ()) {
00053 do {
00054 dest_outline = it.data ();
00055
00056 if (*dest_outline < *outline) {
00057
00058 dest_outline = it.extract ();
00059
00060 it.add_after_then_move (outline);
00061
00062 child_it.add_to_end (dest_outline);
00063 while (!it.at_last ()) {
00064 it.forward ();
00065
00066 dest_outline = it.data ();
00067 if (*dest_outline < *outline) {
00068
00069 dest_outline = it.extract ();
00070 child_it.add_to_end (dest_outline);
00071
00072 if (it.empty ())
00073 break;
00074 }
00075 }
00076 return;
00077 }
00078
00079 else if (*outline < *dest_outline) {
00080 position_outline (outline, dest_outline->child ());
00081
00082 return;
00083 }
00084 it.forward ();
00085 }
00086 while (!it.at_first ());
00087 }
00088 it.add_to_end (outline);
00089 }
00090
00091
00098 #ifndef GRAPHICS_DISABLED
00099 static void plot_outline_list(
00100 OUTLINE_LIST *list,
00101 WINDOW window,
00102 COLOUR colour,
00103 COLOUR child_colour
00104 ) {
00105 OUTLINE *outline;
00106 OUTLINE_IT it = list;
00107
00108 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00109 outline = it.data ();
00110
00111 outline->plot (window, colour);
00112 if (!outline->child ()->empty ())
00113 plot_outline_list (outline->child (), window,
00114 child_colour, child_colour);
00115 }
00116 }
00117 #endif
00118
00119
00126 PBLOB::PBLOB(
00127 OUTLINE_LIST *outline_list
00128 ) {
00129 OUTLINE *outline;
00130 OUTLINE_IT it = outline_list;
00131
00132 while (!it.empty ()) {
00133 outline = it.extract ();
00134
00135 position_outline(outline, &outlines);
00136 if (!it.empty ())
00137 it.forward ();
00138 }
00139 }
00140
00141
00147 static void approximate_outline_list(
00148 C_OUTLINE_LIST *srclist,
00149 OUTLINE_LIST *destlist,
00150 float xheight
00151 ) {
00152 C_OUTLINE *src_outline;
00153 OUTLINE *dest_outline;
00154 C_OUTLINE_IT src_it = srclist;
00155 OUTLINE_IT dest_it = destlist;
00156
00157 do {
00158 src_outline = src_it.data ();
00159
00160 dest_outline = tesspoly_outline (src_outline, xheight);
00161
00162
00163 if (dest_outline != NULL) {
00164 dest_it.add_after_then_move (dest_outline);
00165 if (!src_outline->child ()->empty ())
00166
00167 approximate_outline_list (src_outline->child (), dest_outline->child (), xheight);
00168 }
00169 src_it.forward ();
00170 }
00171 while (!src_it.at_first ());
00172 }
00173
00174
00180 PBLOB::PBLOB(
00181 C_BLOB *cblob,
00182 float xheight
00183 ) {
00184 BOX bbox;
00185
00186 if (!cblob->out_list ()->empty ()) {
00187
00188 bbox = cblob->bounding_box ();
00189 if (bbox.height () > xheight)
00190 xheight = bbox.height ();
00191
00192 approximate_outline_list (cblob->out_list (), &outlines, xheight);
00193 }
00194 }
00195
00196
00202 BOX PBLOB::bounding_box() {
00203 OUTLINE *outline;
00204 OUTLINE_IT it = &outlines;
00205 BOX box;
00206
00207 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00208 outline = it.data ();
00209 box += outline->bounding_box ();
00210 }
00211 return box;
00212 }
00213
00214
00220 float PBLOB::area() {
00221 OUTLINE *outline;
00222 OUTLINE_IT it = &outlines;
00223 float total;
00224
00225 total = 0.0f;
00226 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00227 outline = it.data ();
00228 total += outline->area ();
00229 }
00230 return total;
00231 }
00232
00233
00239 PBLOB *PBLOB::baseline_normalise(
00240 ROW *row,
00241 DENORM *denorm
00242 ) {
00243 BOX blob_box = bounding_box ();
00244 float x_centre = (blob_box.left () + blob_box.right ()) / 2.0;
00245 PBLOB *bn_blob;
00246
00247 *denorm = DENORM (x_centre, bln_x_height / row->x_height (), row);
00248 bn_blob = new PBLOB;
00249 *bn_blob = *this;
00250 bn_blob->move (FCOORD (-denorm->origin (), -row->base_line (x_centre)));
00251 bn_blob->scale (denorm->scale ());
00252 bn_blob->move (FCOORD (0.0, bln_baseline_offset));
00253 return bn_blob;
00254 }
00255
00256
00262 void PBLOB::baseline_denormalise(
00263 const DENORM *denorm
00264 ) {
00265 float blob_x_left;
00266 BOX blob_box;
00267
00268 move(FCOORD (0.0f, 0.0f - bln_baseline_offset));
00269 blob_box = bounding_box ();
00270 blob_x_left = blob_box.left ();
00271 scale (1.0 / denorm->scale_at_x (blob_x_left));
00272 move (FCOORD (denorm->origin (),
00273 denorm->yshift_at_x (blob_x_left)));
00274 }
00275
00276
00282 void PBLOB::move(
00283 const FCOORD vec
00284 ) {
00285 OUTLINE_IT it(&outlines);
00286
00287 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00288 it.data ()->move (vec);
00289 }
00290
00291
00297 void PBLOB::scale(
00298 const float f
00299 ) {
00300 OUTLINE_IT it(&outlines);
00301
00302 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00303 it.data ()->scale (f);
00304 }
00305
00306
00312 void PBLOB::scale(
00313 const FCOORD vec
00314 ) {
00315 OUTLINE_IT it(&outlines);
00316
00317 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00318 it.data ()->scale (vec);
00319 }
00320
00321
00327 #ifndef GRAPHICS_DISABLED
00328 void PBLOB::plot(
00329 WINDOW window,
00330 COLOUR blob_colour,
00331 COLOUR child_colour
00332 ) {
00333 plot_outline_list(&outlines, window, blob_colour, child_colour);
00334 }
00335 #endif