#include "mfcpch.h"
#include "underlin.h"
Go to the source code of this file.
#define EXTERN |
Definition at line 28 of file underlin.cpp.
#define PROJECTION_MARGIN 10 |
Arbitrary.
* (C) Copyright 1994, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License.
Definition at line 27 of file underlin.cpp.
void find_underlined_blobs | ( | BLOBNBOX * | u_line, | |
QSPLINE * | baseline, | |||
float | xheight, | |||
float | baseline_offset, | |||
ICOORDELT_LIST * | chop_cells | |||
) |
Get chop points.
Find the start and end coords of blobs in the underline.
Definition at line 203 of file underlin.cpp.
References ASSERT_HOST, baseline, BOX::left(), NULL, BOX::right(), and vertical_cunderline_projection().
Referenced by restore_underlined_blobs().
00209 { 00210 INT16 x, y; //sides of blob 00211 ICOORD blob_chop; //sides of blob 00212 BOX blob_box = u_line->bounding_box (); 00213 //cell iterator 00214 ICOORDELT_IT cell_it = chop_cells; 00215 STATS upper_proj (blob_box.left (), blob_box.right () + 1); 00216 STATS middle_proj (blob_box.left (), blob_box.right () + 1); 00217 STATS lower_proj (blob_box.left (), blob_box.right () + 1); 00218 C_OUTLINE_IT out_it; //outlines of blob 00219 00220 ASSERT_HOST (u_line->cblob () != NULL); 00221 00222 out_it.set_to_list (u_line->cblob ()->out_list ()); 00223 for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { 00224 vertical_cunderline_projection (out_it.data (), 00225 baseline, xheight, baseline_offset, 00226 &lower_proj, &middle_proj, &upper_proj); 00227 } 00228 00229 for (x = blob_box.left (); x < blob_box.right (); x++) { 00230 if (middle_proj.pile_count (x) > 0) { 00231 for (y = x + 1; 00232 y < blob_box.right () && middle_proj.pile_count (y) > 0; y++); 00233 blob_chop = ICOORD (x, y); 00234 cell_it.add_after_then_move (new ICOORDELT (blob_chop)); 00235 x = y; 00236 } 00237 } 00238 }
Find best row.
Return the row which most overlaps the blob.
Definition at line 147 of file underlin.cpp.
References TO_ROW::ascrise, TO_ROW::baseline, TO_ROW::descdrop, MAX_INT32, NULL, TO_ROW::xheight, and QSPLINE::y().
00150 { 00151 INT16 x = (blob->bounding_box ().left () 00152 + blob->bounding_box ().right ()) / 2; 00153 TO_ROW_IT row_it = rows; //row iterator 00154 TO_ROW *row; //current row 00155 TO_ROW *best_row; //output row 00156 float overlap; //of blob & row 00157 float bestover; //best overlap 00158 00159 best_row = NULL; 00160 bestover = (float) -MAX_INT32; 00161 if (row_it.empty ()) 00162 return NULL; 00163 row = row_it.data (); 00164 row_it.mark_cycle_pt (); 00165 while (row->baseline.y (x) + row->descdrop > blob->bounding_box ().top () 00166 && !row_it.cycled_list ()) { 00167 best_row = row; 00168 bestover = 00169 blob->bounding_box ().top () - row->baseline.y (x) + row->descdrop; 00170 row_it.forward (); 00171 row = row_it.data (); 00172 } 00173 while (row->baseline.y (x) + row->xheight + row->ascrise 00174 >= blob->bounding_box ().bottom () && !row_it.cycled_list ()) { 00175 overlap = row->baseline.y (x) + row->xheight + row->ascrise; 00176 if (blob->bounding_box ().top () < overlap) 00177 overlap = blob->bounding_box ().top (); 00178 if (blob->bounding_box ().bottom () > 00179 row->baseline.y (x) + row->descdrop) 00180 overlap -= blob->bounding_box ().bottom (); 00181 else 00182 overlap -= row->baseline.y (x) + row->descdrop; 00183 if (overlap > bestover) { 00184 bestover = overlap; 00185 best_row = row; 00186 } 00187 row_it.forward (); 00188 row = row_it.data (); 00189 } 00190 if (bestover < 0 00191 && row->baseline.y (x) + row->xheight + row->ascrise 00192 - blob->bounding_box ().bottom () > bestover) 00193 best_row = row; 00194 return best_row; 00195 }
void restore_underlined_blobs | ( | TO_BLOCK * | block | ) |
Get chop points.
Find underlined blobs and put them back in the row.
Definition at line 42 of file underlin.cpp.
References ASSERT_HOST, TO_ROW::baseline, BOX::bottom(), FALSE, find_underlined_blobs(), TO_ROW::insert_blob(), BOX::left(), most_overlapping_row(), NULL, BOX::right(), split_to_blob(), BOX::top(), and TO_ROW::xheight.
Referenced by cleanup_rows().
00044 { 00045 INT16 chop_coord; //chop boundary 00046 BOX blob_box; //of underline 00047 BLOBNBOX *u_line; //underline bit 00048 TO_ROW *row; //best row for blob 00049 ICOORDELT_LIST chop_cells; //blobs to cut out 00050 //real underlines 00051 BLOBNBOX_LIST residual_underlines; 00052 OUTLINE_LIST left_outlines; //in current blob 00053 OUTLINE_LIST right_outlines; //for next blob 00054 C_OUTLINE_LIST left_coutlines; 00055 C_OUTLINE_LIST right_coutlines; 00056 ICOORDELT_IT cell_it = &chop_cells; 00057 //under lines 00058 BLOBNBOX_IT under_it = &block->underlines; 00059 BLOBNBOX_IT ru_it = &residual_underlines; 00060 00061 if (block->get_rows()->empty()) 00062 return; // Don't crash if there are no rows. 00063 for (under_it.mark_cycle_pt (); !under_it.cycled_list (); 00064 under_it.forward ()) { 00065 u_line = under_it.extract (); 00066 blob_box = u_line->bounding_box (); 00067 row = most_overlapping_row (block->get_rows (), u_line); 00068 find_underlined_blobs (u_line, &row->baseline, row->xheight, 00069 row->xheight * textord_underline_offset, 00070 &chop_cells); 00071 cell_it.set_to_list (&chop_cells); 00072 for (cell_it.mark_cycle_pt (); !cell_it.cycled_list (); 00073 cell_it.forward ()) { 00074 chop_coord = cell_it.data ()->x (); 00075 if (cell_it.data ()->y () - chop_coord > textord_fp_chop_error + 1) { 00076 split_to_blob (u_line, chop_coord, 00077 textord_fp_chop_error + 0.5, 00078 &left_outlines, &left_coutlines, 00079 &right_outlines, &right_coutlines); 00080 if (!left_outlines.empty ()) 00081 ru_it. 00082 add_after_then_move (new 00083 BLOBNBOX (new PBLOB (&left_outlines))); 00084 else if (!left_coutlines.empty ()) 00085 ru_it. 00086 add_after_then_move (new 00087 BLOBNBOX (new 00088 C_BLOB (&left_coutlines))); 00089 //right edge of lbob 00090 chop_coord = cell_it.data ()->y (); 00091 split_to_blob (NULL, chop_coord, 00092 textord_fp_chop_error + 0.5, 00093 &left_outlines, &left_coutlines, 00094 &right_outlines, &right_coutlines); 00095 if (!left_outlines.empty ()) 00096 row->insert_blob (new BLOBNBOX (new PBLOB (&left_outlines))); 00097 else if (!left_coutlines.empty ()) 00098 row-> 00099 insert_blob (new BLOBNBOX (new C_BLOB (&left_coutlines))); 00100 else { 00101 ASSERT_HOST(FALSE); 00102 fprintf (stderr, 00103 "Error:no outlines after chopping from %d to %d from (%d,%d)->(%d,%d)\n", 00104 cell_it.data ()->x (), cell_it.data ()->y (), 00105 blob_box.left (), blob_box.bottom (), 00106 blob_box.right (), blob_box.top ()); 00107 } 00108 u_line = NULL; //no more blobs to add 00109 } 00110 delete cell_it.extract (); 00111 } 00112 if (!right_outlines.empty () || !right_coutlines.empty ()) { 00113 split_to_blob (NULL, blob_box.right (), 00114 textord_fp_chop_error + 0.5, 00115 &left_outlines, &left_coutlines, 00116 &right_outlines, &right_coutlines); 00117 if (!left_outlines.empty ()) 00118 ru_it. 00119 add_after_then_move (new BLOBNBOX (new PBLOB (&left_outlines))); 00120 else if (!left_coutlines.empty ()) 00121 ru_it. 00122 add_after_then_move (new 00123 BLOBNBOX (new C_BLOB (&left_coutlines))); 00124 } 00125 if (u_line != NULL) { 00126 if (u_line->blob() != NULL) 00127 delete u_line->blob(); 00128 if (u_line->cblob() != NULL) 00129 delete u_line->cblob(); 00130 delete u_line; 00131 } 00132 } 00133 if (!ru_it.empty ()) { 00134 ru_it.move_to_first (); 00135 for (ru_it.mark_cycle_pt (); !ru_it.cycled_list (); ru_it.forward ()) { 00136 under_it.add_after_then_move (ru_it.extract ()); 00137 } 00138 } 00139 }
void vertical_cunderline_projection | ( | C_OUTLINE * | outline, | |
QSPLINE * | baseline, | |||
float | xheight, | |||
float | baseline_offset, | |||
STATS * | lower_proj, | |||
STATS * | middle_proj, | |||
STATS * | upper_proj | |||
) |
Project outlines.
Compute the vertical projection of a outline from its outlines and add to the given STATS.
Definition at line 247 of file underlin.cpp.
References STATS::add(), baseline, vertical_cunderline_projection(), and ICOORD::y().
Referenced by find_underlined_blobs(), and vertical_cunderline_projection().
00255 { 00256 ICOORD pos; //current point 00257 ICOORD step; //edge step 00258 INT16 lower_y, upper_y; //region limits 00259 INT32 length; //of outline 00260 INT16 stepindex; //current step 00261 C_OUTLINE_IT out_it = outline->child (); 00262 00263 pos = outline->start_pos (); 00264 length = outline->pathlength (); 00265 for (stepindex = 0; stepindex < length; stepindex++) { 00266 step = outline->step (stepindex); 00267 if (step.x () > 0) { 00268 lower_y = 00269 (INT16) floor (baseline->y (pos.x ()) + baseline_offset + 0.5); 00270 upper_y = 00271 (INT16) floor (baseline->y (pos.x ()) + baseline_offset + 00272 xheight + 0.5); 00273 if (pos.y () >= lower_y) { 00274 lower_proj->add (pos.x (), -lower_y); 00275 if (pos.y () >= upper_y) { 00276 middle_proj->add (pos.x (), lower_y - upper_y); 00277 upper_proj->add (pos.x (), upper_y - pos.y ()); 00278 } 00279 else 00280 middle_proj->add (pos.x (), lower_y - pos.y ()); 00281 } 00282 else 00283 lower_proj->add (pos.x (), -pos.y ()); 00284 } 00285 else if (step.x () < 0) { 00286 lower_y = 00287 (INT16) floor (baseline->y (pos.x () - 1) + baseline_offset + 00288 0.5); 00289 upper_y = 00290 (INT16) floor (baseline->y (pos.x () - 1) + baseline_offset + 00291 xheight + 0.5); 00292 if (pos.y () >= lower_y) { 00293 lower_proj->add (pos.x () - 1, lower_y); 00294 if (pos.y () >= upper_y) { 00295 middle_proj->add (pos.x () - 1, upper_y - lower_y); 00296 upper_proj->add (pos.x () - 1, pos.y () - upper_y); 00297 } 00298 else 00299 middle_proj->add (pos.x () - 1, pos.y () - lower_y); 00300 } 00301 else 00302 lower_proj->add (pos.x () - 1, pos.y ()); 00303 } 00304 pos += step; 00305 } 00306 00307 for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { 00308 vertical_cunderline_projection (out_it.data (), 00309 baseline, xheight, baseline_offset, 00310 lower_proj, middle_proj, upper_proj); 00311 } 00312 }