• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**********************************************************************
2  * File:        ocrblock.cpp  (Formerly block.c)
3  * Description: BLOCK member functions and iterator functions.
4  * Author:		Ray Smith
5  * Created:		Fri Mar 15 09:41:28 GMT 1991
6  *
7  * (C) Copyright 1991, Hewlett-Packard Ltd.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  *
18  **********************************************************************/
19 
20 #include "mfcpch.h"
21 #include          <stdlib.h>
22 #include          "blckerr.h"
23 #include          "ocrblock.h"
24 #include          "tprintf.h"
25 
26 #define BLOCK_LABEL_HEIGHT  150  //char height of block id
27 
ELISTIZE_S(BLOCK)28 ELISTIZE_S (BLOCK)
29 /**********************************************************************
30  * BLOCK::BLOCK
31  *
32  * Constructor for a simple rectangular block.
33  **********************************************************************/
34 BLOCK::BLOCK(const char *name,                //filename
35 BOOL8 prop,                      //proportional
36 inT16 kern,                      //kerning
37 inT16 space,                     //spacing
38 inT16 xmin,                      //bottom left
39 inT16 ymin, inT16 xmax,          //top right
40              inT16 ymax)
41   : PDBLK (xmin, ymin, xmax, ymax),
42     filename(name),
43     re_rotation_(1.0f, 0.0f),
44     classify_rotation_(1.0f, 0.0f),
45     skew_(1.0f, 0.0f) {
46   ICOORDELT_IT left_it = &leftside;
47   ICOORDELT_IT right_it = &rightside;
48 
49   proportional = prop;
50   kerning = kern;
51   spacing = space;
52   font_class = -1;               //not assigned
53   cell_over_xheight_ = 2.0f;
54   hand_poly = NULL;
55   left_it.set_to_list (&leftside);
56   right_it.set_to_list (&rightside);
57                                  //make default box
58   left_it.add_to_end (new ICOORDELT (xmin, ymin));
59   left_it.add_to_end (new ICOORDELT (xmin, ymax));
60   right_it.add_to_end (new ICOORDELT (xmax, ymin));
61   right_it.add_to_end (new ICOORDELT (xmax, ymax));
62 }
63 
64 /**********************************************************************
65  * decreasing_top_order
66  *
67  * Sort Comparator: Return <0 if row1 top < row2 top
68  **********************************************************************/
69 
decreasing_top_order(const void * row1,const void * row2)70 int decreasing_top_order(  //
71                          const void *row1,
72                          const void *row2) {
73   return (*(ROW **) row2)->bounding_box ().top () -
74     (*(ROW **) row1)->bounding_box ().top ();
75 }
76 
77 
78 /**********************************************************************
79  * BLOCK::rotate
80  *
81  * Rotate the polygon by the given rotation and recompute the bounding_box.
82  **********************************************************************/
rotate(const FCOORD & rotation)83 void BLOCK::rotate(const FCOORD& rotation) {
84   poly_block()->rotate(rotation);
85   box = *poly_block()->bounding_box();
86 }
87 
88 /**********************************************************************
89  * BLOCK::sort_rows
90  *
91  * Order rows so that they are in order of decreasing Y coordinate
92  **********************************************************************/
93 
sort_rows()94 void BLOCK::sort_rows() {  // order on "top"
95   ROW_IT row_it(&rows);
96 
97   row_it.sort (decreasing_top_order);
98 }
99 
100 
101 /**********************************************************************
102  * BLOCK::compress
103  *
104  * Delete space between the rows. (And maybe one day, compress the rows)
105  * Fill space of block from top down, left aligning rows.
106  **********************************************************************/
107 
compress()108 void BLOCK::compress() {  // squash it up
109   #define           ROW_SPACING 5
110 
111   ROW_IT row_it(&rows);
112   ROW *row;
113   ICOORD row_spacing (0, ROW_SPACING);
114 
115   ICOORDELT_IT icoordelt_it;
116 
117   sort_rows();
118 
119   box = TBOX (box.topleft (), box.topleft ());
120   box.move_bottom_edge (ROW_SPACING);
121   for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
122     row = row_it.data ();
123     row->move (box.botleft () - row_spacing -
124       row->bounding_box ().topleft ());
125     box += row->bounding_box ();
126   }
127 
128   leftside.clear ();
129   icoordelt_it.set_to_list (&leftside);
130   icoordelt_it.add_to_end (new ICOORDELT (box.left (), box.bottom ()));
131   icoordelt_it.add_to_end (new ICOORDELT (box.left (), box.top ()));
132   rightside.clear ();
133   icoordelt_it.set_to_list (&rightside);
134   icoordelt_it.add_to_end (new ICOORDELT (box.right (), box.bottom ()));
135   icoordelt_it.add_to_end (new ICOORDELT (box.right (), box.top ()));
136 }
137 
138 
139 /**********************************************************************
140  * BLOCK::check_pitch
141  *
142  * Check whether the block is fixed or prop, set the flag, and set
143  * the pitch if it is fixed.
144  **********************************************************************/
145 
check_pitch()146 void BLOCK::check_pitch() {  // check prop
147   //      tprintf("Missing FFT fixed pitch stuff!\n");
148   pitch = -1;
149 }
150 
151 
152 /**********************************************************************
153  * BLOCK::compress
154  *
155  * Compress and move in a single operation.
156  **********************************************************************/
157 
compress(const ICOORD vec)158 void BLOCK::compress(                  // squash it up
159                      const ICOORD vec  // and move
160                     ) {
161   box.move (vec);
162   compress();
163 }
164 
165 
166 /**********************************************************************
167  * BLOCK::print
168  *
169  * Print the info on a block
170  **********************************************************************/
171 
print(FILE *,BOOL8 dump)172 void BLOCK::print(            //print list of sides
173                   FILE *,     //file to print on
174                   BOOL8 dump  //print full detail
175                  ) {
176   ICOORDELT_IT it = &leftside;   //iterator
177 
178   box.print ();
179   tprintf ("Proportional= %s\n", proportional ? "TRUE" : "FALSE");
180   tprintf ("Kerning= %d\n", kerning);
181   tprintf ("Spacing= %d\n", spacing);
182   tprintf ("Fixed_pitch=%d\n", pitch);
183   tprintf ("Filename= %s\n", filename.string ());
184 
185   if (dump) {
186     tprintf ("Left side coords are:\n");
187     for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
188       tprintf ("(%d,%d) ", it.data ()->x (), it.data ()->y ());
189     tprintf ("\n");
190     tprintf ("Right side coords are:\n");
191     it.set_to_list (&rightside);
192     for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
193       tprintf ("(%d,%d) ", it.data ()->x (), it.data ()->y ());
194     tprintf ("\n");
195   }
196 }
197 
198 /**********************************************************************
199  * BLOCK::operator=
200  *
201  * Assignment - duplicate the block structure, but with an EMPTY row list.
202  **********************************************************************/
203 
operator =(const BLOCK & source)204 BLOCK & BLOCK::operator= (       //assignment
205 const BLOCK & source             //from this
206 ) {
207   this->ELIST_LINK::operator= (source);
208   this->PDBLK::operator= (source);
209   proportional = source.proportional;
210   kerning = source.kerning;
211   spacing = source.spacing;
212   filename = source.filename;    //STRINGs assign ok
213   if (!rows.empty ())
214     rows.clear ();
215   re_rotation_ = source.re_rotation_;
216   classify_rotation_ = source.classify_rotation_;
217   skew_ = source.skew_;
218   return *this;
219 }
220