• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * File:        blkocc.h  (Formerly blockocc.h)
4  * Description:  Block Occupancy routines
5  * Author:       Chris Newton
6  * Created:      Fri Nov 8
7  * Modified:
8  * Language:     C++
9  * Package:      N/A
10  * Status:       Experimental (Do Not Distribute)
11  *
12  * (c) Copyright 1991, Hewlett-Packard Company.
13  ** Licensed under the Apache License, Version 2.0 (the "License");
14  ** you may not use this file except in compliance with the License.
15  ** You may obtain a copy of the License at
16  ** http://www.apache.org/licenses/LICENSE-2.0
17  ** Unless required by applicable law or agreed to in writing, software
18  ** distributed under the License is distributed on an "AS IS" BASIS,
19  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  ** See the License for the specific language governing permissions and
21  ** limitations under the License.
22  *
23  ******************************************************************************/
24 
25 #ifndef           BLKOCC_H
26 #define           BLKOCC_H
27 
28 #include                   "varable.h"
29 #include                   "polyblob.h"
30 #include          "elst.h"
31 #include          "notdll.h"
32 #include          "notdll.h"
33 
34 /***************************************************************************
35 CLASS REGION_OCC
36 
37   The class REGION_OCC defines a section of outline which exists entirely
38   within a single region. The only data held is the min and max x limits of
39   the outline within the region.
40 
41   REGION_OCCs are held on lists, one list for each region.  The lists are
42   built in sorted order of min x. Overlapping REGION_OCCs are not permitted on
43   a single list. An overlapping region to be added causes the existing region
44   to be extended. This extension may result in the following REGION_OCC on the
45   list overlapping the ammended one. In this case the ammended REGION_OCC is
46   further extended to include the range of the following one, so that the
47   following one can be deleted.
48 
49 ****************************************************************************/
50 
51 class REGION_OCC:public ELIST_LINK
52 {
53   public:
54     float min_x;                 //Lowest x in region
55     float max_x;                 //Highest x in region
56     inT16 region_type;           //Type of crossing
57 
REGION_OCC()58     REGION_OCC() {
59     };                           //constructor used
60     //only in COPIER etc
REGION_OCC(float min,float max,inT16 region)61     REGION_OCC(  //constructor
62                float min,
63                float max,
64                inT16 region) {
65       min_x = min;
66       max_x = max;
67       region_type = region;
68     }
69 };
70 
ELISTIZEH(REGION_OCC)71 ELISTIZEH (REGION_OCC)
72 #define RANGE_IN_BAND( band_max, band_min, range_max, range_min ) \
73 ( ((range_min) >= (band_min)) && ((range_max) < (band_max)) ) ? TRUE : FALSE
74 /************************************************************************
75 Adapted from the following procedure so that it can be used in the bands
76 class in an include file...
77 
78 BOOL8						range_in_band[
79               range within band?
80 inT16						band_max,
81 inT16						band_min,
82 inT16						range_max,
83 inT16						range_min]
84 {
85   if ( (range_min >= band_min) && (range_max < band_max) )
86     return TRUE;
87   else
88     return FALSE;
89 }
90 ***********************************************************************/
91 #define RANGE_OVERLAPS_BAND( band_max, band_min, range_max, range_min ) \
92 ( ((range_max) >= (band_min)) && ((range_min) < (band_max)) ) ? TRUE : FALSE
93 /************************************************************************
94 Adapted from the following procedure so that it can be used in the bands
95 class in an include file...
96 
97 BOOL8						range_overlaps_band[
98               range crosses band?
99 inT16						band_max,
100 inT16						band_min,
101 inT16						range_max,
102 inT16						range_min]
103 {
104   if ( (range_max >= band_min) && (range_min < band_max) )
105     return TRUE;
106   else
107     return FALSE;
108 }
109 ***********************************************************************/
110 /**********************************************************************
111   Bands
112   -----
113 
114   BAND 4
115 --------------------------------
116   BAND 3
117 --------------------------------
118 
119   BAND 2
120 
121 --------------------------------
122 
123   BAND 1
124 
125 Band 0 is the dot band
126 
127 Each band has an error margin above and below. An outline is not considered to
128 have significantly changed bands until it has moved out of the error margin.
129 *************************************************************************/
130 class BAND
131 {
132   public:
133     inT16 max_max;               //upper max
134     inT16 max;                   //nominal max
135     inT16 min_max;               //lower max
136     inT16 max_min;               //upper min
137     inT16 min;                   //nominal min
138     inT16 min_min;               //lower min
139 
140     BAND() {
141     }                            // constructor
142 
143     void set(                      // initialise a band
144              inT16 new_max_max,    // upper max
145              inT16 new_max,        // new nominal max
146              inT16 new_min_max,    // new lower max
147              inT16 new_max_min,    // new upper min
148              inT16 new_min,        // new nominal min
149              inT16 new_min_min) {  // new lower min
150       max_max = new_max_max;
151       max = new_max;
152       min_max = new_min_max;
153       max_min = new_max_min;
154       min = new_min;
155       min_min = new_min_min;
156     }
157 
158     BOOL8 in_minimal(            //in minimal limits?
159                      float y) {  //y value
160       if ((y >= max_min) && (y < min_max))
161         return TRUE;
162       else
163         return FALSE;
164     }
165 
166     BOOL8 in_nominal(            //in nominal limits?
167                      float y) {  //y value
168       if ((y >= min) && (y < max))
169         return TRUE;
170       else
171         return FALSE;
172     }
173 
174     BOOL8 in_maximal(            //in maximal limits?
175                      float y) {  //y value
176       if ((y >= min_min) && (y < max_max))
177         return TRUE;
178       else
179         return FALSE;
180     }
181 
182                                  //overlaps min limits?
183     BOOL8 range_overlaps_minimal(float y1,    //one range limit
184                                  float y2) {  //other range limit
185       if (y1 > y2)
186         return RANGE_OVERLAPS_BAND (min_max, max_min, y1, y2);
187       else
188         return RANGE_OVERLAPS_BAND (min_max, max_min, y2, y1);
189     }
190 
191                                  //overlaps nom limits?
192     BOOL8 range_overlaps_nominal(float y1,    //one range limit
193                                  float y2) {  //other range limit
194       if (y1 > y2)
195         return RANGE_OVERLAPS_BAND (max, min, y1, y2);
196       else
197         return RANGE_OVERLAPS_BAND (max, min, y2, y1);
198     }
199 
200                                  //overlaps max limits?
201     BOOL8 range_overlaps_maximal(float y1,    //one range limit
202                                  float y2) {  //other range limit
203       if (y1 > y2)
204         return RANGE_OVERLAPS_BAND (max_max, min_min, y1, y2);
205       else
206         return RANGE_OVERLAPS_BAND (max_max, min_min, y2, y1);
207     }
208 
209     BOOL8 range_in_minimal(             //within min limits?
210                            float y1,    //one range limit
211                            float y2) {  //other range limit
212       if (y1 > y2)
213         return RANGE_IN_BAND (min_max, max_min, y1, y2);
214       else
215         return RANGE_IN_BAND (min_max, max_min, y2, y1);
216     }
217 
218     BOOL8 range_in_nominal(             //within nom limits?
219                            float y1,    //one range limit
220                            float y2) {  //other range limit
221       if (y1 > y2)
222         return RANGE_IN_BAND (max, min, y1, y2);
223       else
224         return RANGE_IN_BAND (max, min, y2, y1);
225     }
226 
227     BOOL8 range_in_maximal(             //within max limits?
228                            float y1,    //one range limit
229                            float y2) {  //other range limit
230       if (y1 > y2)
231         return RANGE_IN_BAND (max_max, min_min, y1, y2);
232       else
233         return RANGE_IN_BAND (max_max, min_min, y2, y1);
234     }
235 };
236 
237 /* Standard positions */
238 
239 #define MAX_NUM_BANDS 5
240 #define UNDEFINED_BAND 99
241 #define NO_LOWER_LIMIT -9999
242 #define NO_UPPER_LIMIT 9999
243 
244 #define DOT_BAND 0
245 
246 /* Special occupancy code emitted for the 0 region at the end of a word */
247 
248 #define END_OF_WERD_CODE 255
249 
250 extern BOOL_VAR_H (blockocc_show_result, FALSE, "Show intermediate results");
251 extern INT_VAR_H (blockocc_desc_height, 0,
252 "Descender height after normalisation");
253 extern INT_VAR_H (blockocc_asc_height, 255,
254 "Ascender height after normalisation");
255 extern INT_VAR_H (blockocc_band_count, 4, "Number of bands used");
256 extern double_VAR_H (textord_underline_threshold, 0.9,
257 "Fraction of width occupied");
258 BOOL8 test_underline(                   //look for underlines
259                      BOOL8 testing_on,  //drawing blob
260                      PBLOB *blob,       //blob to test
261                      float baseline,    //coords of baseline
262                      float xheight      //height of line
263                     );
264 BOOL8 test_underline(                   //look for underlines
265                      BOOL8 testing_on,  //drawing blob
266                      C_BLOB *blob,      //blob to test
267                      inT16 baseline,    //coords of baseline
268                      inT16 xheight      //height of line
269                     );
270                                  //project outlines
271 void horizontal_cblob_projection(C_BLOB *blob,  //blob to project
272                                  STATS *stats   //output
273                                 );
274 void horizontal_coutline_projection(                     //project outlines
275                                     C_OUTLINE *outline,  //outline to project
276                                     STATS *stats         //output
277                                    );
278 void set_bands(                 //init from varibles
279                float baseline,  //top of bottom band
280                float xheight    //height of split band
281               );
282 void block_occ (PBLOB * blob,    //blob to do
283 float occs[]                     //output histogram
284 );
285                                  //blob to do
286 void find_transitions(PBLOB *blob, REGION_OCC_LIST *region_occ_list);
287 void record_region(  //add region on list
288                    inT16 band,
289                    float new_min,
290                    float new_max,
291                    inT16 region_type,
292                    REGION_OCC_LIST *region_occ_list);
293 inT16 find_containing_maximal_band(  //find range's band
294                                    float y1,
295                                    float y2,
296                                    BOOL8 *doubly_contained);
297 void find_significant_line(POLYPT_IT it, inT16 *band);
298 inT16 find_overlapping_minimal_band(  //find range's band
299                                     float y1,
300                                     float y2);
301 inT16 find_region_type(inT16 entry_band,
302                        inT16 current_band,
303                        inT16 exit_band,
304                        float entry_x,
305                        float exit_x);
306 void find_trans_point(POLYPT_IT *pt_it,
307                       inT16 current_band,
308                       inT16 next_band,
309                       FCOORD *transition_pt);
310 void next_region(POLYPT_IT *start_pt_it,
311                  inT16 start_band,
312                  inT16 *to_band,
313                  float *min_x,
314                  float *max_x,
315                  inT16 *increment,
316                  FCOORD *exit_pt);
317 inT16 find_band(  // find POINT's band
318                 float y);
319 void compress_region_list(  // join open regions
320                           REGION_OCC_LIST *region_occ_list);
321 void find_fbox(OUTLINE_IT *out_it,
322                float *min_x,
323                float *min_y,
324                float *max_x,
325                float *max_y);
326 void maintain_limits(float *min_x, float *max_x, float x);
327 #endif
328