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