~ubuntu-branches/ubuntu/precise/cuneiform/precise

« back to all changes in this revision

Viewing changes to cuneiform_src/Kern/rbal/src/linutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Jakub Wilk, c-assert.diff, slovenian-slv.diff
  • Date: 2011-01-26 21:53:07 UTC
  • mfrom: (5.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20110126215307-62x61mcesr607qb7
Tags: 1.0.0+dfsg-2
* Upload to unstable.
* Explicitly build-depend on pkg-config. Thanks to Stefano Rivera for the
  bug report.
* Add Vcs-* fields.
* Use the standard C assert() macro, rather than custom Cuneiform one.
  [c-assert.diff]
* Pass CFLAGS, CXXFLAGS and LDFLAGS (get from dpkg-buildflags) to cmake
  (closes: #608345). Thanks to Sami Liedes for the bug report.
  + Build depend on dpkg-dev (>= 1.15.7).
* Pass --parallel to dh.
  + Bump debhelper minimum version to 7.4.10.
* Update debian/copyright to the latest DEP-5 version.
* Bump year in debian/copyright.
* Explicitly link to GraphicsMagick (rather than via the ImageMagick
  compatibility layer).
* Don't ship /usr/lib/cuneiform/*.so symlinks. These libraries are
  considered private, at least until #598616 is fixed.
* Rename some private variables in debian/rules to make them lowercase.
* Update patch headers.
* Provide proper ‘build-arch’ and ‘build-indep’ targets in debian/rules.
* Document input format in the manual page (closes: #572061). Thanks to
  Janusz S. Bień for the bug report.
* Use ‘slv’ (rather than ‘slo’) as language code for Slovenian.
  [slovenian-slv.diff]
* Fix package description: Slovenian is supported, Slovak is not.
* Improve documentation of the language (-l) option (closes: #602512).
  Thanks to Jari Aalto for the bug report.
* Install reasons file for vrms.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
Copyright (c) 1993-2008, Cognitive Technologies
3
 
All rights reserved.
4
 
 
5
 
����������� ��������� ��������������� � ������������� ��� � ���� ��������� ����,
6
 
��� � � �������� �����, � ����������� ��� ���, ��� ���������� ��������� �������:
7
 
 
8
 
      * ��� ��������� ��������������� ��������� ���� ������ ���������� ���������
9
 
        ���� ����������� �� ��������� �����, ���� ������ ������� � �����������
10
 
        ����� �� ��������.
11
 
      * ��� ��������� ��������������� ��������� ���� � ������������ �/��� �
12
 
        ������ ����������, ������������ ��� ���������������, ������ �����������
13
 
        ��������� ���� ���������� �� ��������� �����, ���� ������ ������� �
14
 
        ����������� ����� �� ��������.
15
 
      * �� �������� Cognitive Technologies, �� ����� �� ����������� �� �����
16
 
        ���� ������������ � �������� �������� ��������� �/��� �����������
17
 
        ���������, ���������� �� ���� ��, ��� ���������������� �����������
18
 
        ����������.
19
 
 
20
 
��� ��������� ������������� ����������� ��������� ���� �/��� ������� ������ "���
21
 
��� ����" ��� ������-���� ���� ��������, ���������� ���� ��� ���������������,
22
 
������� �������� ������������ �������� � ����������� ��� ���������� ����, �� ��
23
 
������������� ���. �� �������� ��������� ���� � �� ���� ������ ����, �������
24
 
����� �������� �/��� �������� �������������� ���������, �� � ���� ������ ��
25
 
��Ѩ� ���������������, ������� ����� �����, ���������, ����������� ���
26
 
������������� ������, ��������� � �������������� ��� ���������� ����������
27
 
������������� ������������� ��������� (������� ������ ������, ��� ������,
28
 
������� ���������, ��� ������ �/��� ������ �������, ���������� ��-�� ��������
29
 
������� ��� �/��� ������ ��������� �������� ��������� � ������� �����������,
30
 
�� �� ������������� ����� ��������), �� �� ������������� ���, ���� ���� �����
31
 
�������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
32
 
 
33
 
Redistribution and use in source and binary forms, with or without modification,
34
 
are permitted provided that the following conditions are met:
35
 
 
36
 
    * Redistributions of source code must retain the above copyright notice,
37
 
      this list of conditions and the following disclaimer.
38
 
    * Redistributions in binary form must reproduce the above copyright notice,
39
 
      this list of conditions and the following disclaimer in the documentation
40
 
      and/or other materials provided with the distribution.
41
 
    * Neither the name of the Cognitive Technologies nor the names of its
42
 
      contributors may be used to endorse or promote products derived from this
43
 
      software without specific prior written permission.
44
 
 
45
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
46
 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47
 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48
 
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
49
 
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50
 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51
 
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
52
 
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53
 
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
54
 
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55
 
*/
 
2
 Copyright (c) 1993-2008, Cognitive Technologies
 
3
 All rights reserved.
 
4
 
 
5
 ����������� ��������� ��������������� � ������������� ��� � ���� ��������� ����,
 
6
 ��� � � �������� �����, � ����������� ��� ���, ��� ���������� ��������� �������:
 
7
 
 
8
 * ��� ��������� ��������������� ��������� ���� ������ ���������� ���������
 
9
 ���� ����������� �� ��������� �����, ���� ������ ������� � �����������
 
10
 ����� �� ��������.
 
11
 * ��� ��������� ��������������� ��������� ���� � ������������ �/��� �
 
12
 ������ ����������, ������������ ��� ���������������, ������ �����������
 
13
 ��������� ���� ���������� �� ��������� �����, ���� ������ ������� �
 
14
 ����������� ����� �� ��������.
 
15
 * �� �������� Cognitive Technologies, �� ����� �� ����������� �� �����
 
16
 ���� ������������ � �������� �������� ��������� �/��� �����������
 
17
 ���������, ���������� �� ���� ��, ��� ���������������� �����������
 
18
 ����������.
 
19
 
 
20
 ��� ��������� ������������� ����������� ��������� ���� �/��� ������� ������ "���
 
21
 ��� ����" ��� ������-���� ���� ��������, ���������� ���� ��� ���������������,
 
22
 ������� �������� ������������ �������� � ����������� ��� ���������� ����, �� ��
 
23
 ������������� ���. �� �������� ��������� ���� � �� ���� ������ ����, �������
 
24
 ����� �������� �/��� �������� �������������� ���������, �� � ���� ������ ��
 
25
 ��Ѩ� ���������������, ������� ����� �����, ���������, ����������� ���
 
26
 ������������� ������, ��������� � �������������� ��� ���������� ����������
 
27
 ������������� ������������� ��������� (������� ������ ������, ��� ������,
 
28
 ������� ���������, ��� ������ �/��� ������ �������, ���������� ��-�� ��������
 
29
 ������� ��� �/��� ������ ��������� �������� ��������� � ������� �����������,
 
30
 �� �� ������������� ����� ��������), �� �� ������������� ���, ���� ���� �����
 
31
 �������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
 
32
 
 
33
 Redistribution and use in source and binary forms, with or without modification,
 
34
 are permitted provided that the following conditions are met:
 
35
 
 
36
 * Redistributions of source code must retain the above copyright notice,
 
37
 this list of conditions and the following disclaimer.
 
38
 * Redistributions in binary form must reproduce the above copyright notice,
 
39
 this list of conditions and the following disclaimer in the documentation
 
40
 and/or other materials provided with the distribution.
 
41
 * Neither the name of the Cognitive Technologies nor the names of its
 
42
 contributors may be used to endorse or promote products derived from this
 
43
 software without specific prior written permission.
 
44
 
 
45
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 
46
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
47
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
48
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 
49
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
50
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
51
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
52
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
53
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
54
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
55
 */
56
56
 
57
57
#include <stdlib.h>
58
58
#include <stdio.h>
59
59
#include <string.h>
60
60
 
61
61
#include "tuner.h"
62
 
#include "nt_types.h"
63
 
//#include "struct.h"
64
 
//#include "func.h"
65
62
#include "cstr.h"
66
63
 
67
64
#include "linear.h"
68
 
//#include "lang.h"
69
65
#include "linutil.h"
70
66
#include "ligas.h"      // Pit 10-10-94 03:56pm
71
67
#include "minmax.h"
72
68
 
73
69
/*============= Func prototypes ==================*/
74
70
 
75
 
BYTE to_lower(BYTE c);
76
 
BYTE to_upper(BYTE c);
77
 
INT  is_lower(BYTE ch);
78
 
INT  is_upper(BYTE ch);
79
 
INT  isletter(BYTE ch);
80
 
BYTE get_homot(BYTE ch);
81
 
INT  twin(BYTE ch);
82
 
INT  count_line_hi(void);
83
 
INT  draft_cut_hyps(INT bs,INT fl);
 
71
uchar to_lower(uchar c);
 
72
uchar to_upper(uchar c);
 
73
int16_t is_lower(uchar ch);
 
74
int16_t is_upper(uchar ch);
 
75
int16_t isletter(uchar ch);
 
76
uchar get_homot(uchar ch);
 
77
int16_t twin(uchar ch);
 
78
int16_t count_line_hi(void);
 
79
int16_t draft_cut_hyps(int16_t bs, int16_t fl);
84
80
 
85
81
#define MAX_HEIGHT 70  // such was...  change ?
86
 
 
87
 
extern Word8 language;
88
 
 
89
 
extern BYTE db_status    ;    // snap presence byte
90
 
extern BYTE db_trace_flag;    // snap-detail presence byte
91
 
extern BYTE db_pass      ;    // snap-pass indicator
92
 
extern BYTE fEdCode      ;    // Change code letter in module LINUTIL.C
 
82
extern uchar language;
 
83
 
 
84
extern uchar db_status; // snap presence byte
 
85
extern uchar db_trace_flag; // snap-detail presence byte
 
86
extern uchar db_pass; // snap-pass indicator
 
87
extern uchar fEdCode; // Change code letter in module LINUTIL.C
93
88
 
94
89
/*============= Local function portotypes ==============*/
95
90
 
96
 
/*static*/ INT  h_hist(void);
 
91
/*static*/int16_t h_hist(void);
97
92
 
98
93
/*============= Source code ============*/
99
 
BOOL is_liga_ff(BYTE c)
100
 
{
101
 
// ��� ���� ��������� ����� ����� � ligas.h 05.09.2000 E.P.
102
 
  return (c==liga_ff);
103
 
}
104
 
BOOL is_liga_ffl(BYTE c)
105
 
{
106
 
// ��� ���� ��������� ����� ����� � ligas.h 05.09.2000 E.P.
107
 
  return (c==liga_ffl);
108
 
}
109
 
 
110
 
/*   not used
111
 
INT is_russian(BYTE ch)
112
 
{
113
 
if( language==LANG_RUSSIAN || language==LANG_ENGLISH && multy_language )
114
 
switch(fEdCode){
115
 
  case ED_ASCII: // for ASCII
116
 
   if((ch >=(BYTE)'�' && ch <=(BYTE)'�') ||
117
 
      (ch >=(BYTE)'�' && ch <=(BYTE)'�') ||
118
 
      (ch >=(BYTE)'�' && ch <=(BYTE)'�') ||
119
 
       memchr("��������",ch,8)
120
 
     ) return 1;
121
 
  break;
122
 
  case ED_WIN: // for Windows (ANSI)
123
 
      if( (ch >=0xE0 && ch <=0xFF)||(ch >=(BYTE)'�' && ch <=(BYTE)'�'))
124
 
        return 1;
125
 
  break;
126
 
  case ED_MAC: // for Macintosh
127
 
      if(
128
 
       (ch >=0xE0 && ch <=0xFE) || ch == 0xDF || (ch >= 0xC0 && ch <= 0xDF)
129
 
        ) return 1;
130
 
  break;
131
 
        }
132
 
return 0;
133
 
}
134
 
*/
135
 
 
136
 
INT is_english(BYTE ch)
137
 
{
138
 
return (ch >= 'a' && ch <= 'z')||(ch >= 'A' && ch <= 'Z')||
139
 
       (
140
 
//         ch>=ligas_beg && ch<=ligas_end &&
141
 
           is_liga(ch) &&  // 14.09.2000 E.P.
142
 
 
143
 
           ch!=liga_exm && ch!=liga_qm )
144
 
           ;
145
 
}
146
 
 
147
 
INT is_serbian_special(BYTE ch)
148
 
{
149
 
return (ch == SERB_j  ||   ch == SERB_J  ||
150
 
        ch == SERB_n  ||   ch == SERB_N  ||
151
 
        ch == SERB_l  ||   ch == SERB_L  ||
152
 
        ch == SERB_h  ||   ch == SERB_H  ||
153
 
        ch == SERB_hh ||   ch == SERB_HH ||
154
 
        ch == SERB_u  ||   ch == SERB_U  );
155
 
 
156
 
}
157
 
 
158
 
INT is_polish_special(BYTE ch)
159
 
{
160
 
return (ch == POLISH_SS  ||   ch == POLISH_s  ||
161
 
        ch == POLISH_ZZD ||   ch == POLISH_zd ||
162
 
        ch == POLISH_ZZR ||   ch == POLISH_zr ||
163
 
        ch == POLISH_LL  ||   ch == POLISH_l  ||
164
 
        ch == POLISH_AA  ||   ch == POLISH_a  ||
165
 
        ch == POLISH_CC  ||   ch == POLISH_a  ||
166
 
        ch == POLISH_NN  ||   ch == POLISH_n  ||
167
 
        ch == POLISH_EE  ||   ch == POLISH_e  ||
168
 
        ch == POLISH_OO  ||   ch == POLISH_o
169
 
    );
170
 
}
171
 
 
172
 
INT is_czech_special(BYTE let)
173
 
{
174
 
return (
175
 
     let == AA_right_accent || let == a_right_accent    ||
176
 
     let == CC_inv_roof         || let == c_inv_roof            ||
177
 
     let == DD_inv_roof         || let == d_inv_roof            ||
178
 
     let == EE_right_accent || let == e_right_accent    ||
179
 
     let == EE_inv_roof         || let == e_inv_roof            ||
180
 
     let == II_right_accent || let == i_right_accent    ||
181
 
     let == NN_inv_roof         || let == n_inv_roof            ||
182
 
     let == OO_right_accent || let == o_right_accent    ||
183
 
     let == RR_inv_roof         || let == r_inv_roof            ||
184
 
     let == SS_inv_roof         || let == s_inv_roof            ||
185
 
     let == TT_inv_roof         || let == t_inv_roof            ||
186
 
     let == UU_right_accent || let == u_right_accent    ||
187
 
     let == UU_circle_accent|| let == u_circle_accent   ||
188
 
     let == YY_right_accent || let == y_right_accent    ||
189
 
     let == ZZ_inv_roof         || let == z_inv_roof
190
 
    );
191
 
}
192
 
 
193
 
INT is_roman_special(BYTE let)
194
 
{
195
 
return (
196
 
     let == AA_semicircle                       ||      let == a_semicircle                     ||
197
 
     let == AA_roof_accent                      ||      let == a_roof_accent            ||
198
 
     let == II_roof_accent                      ||      let == i_roof_accent            ||
199
 
     let == SS_bottom_accent_latin      ||      let == s_bottom_accent_latin||
200
 
     let == TT_bottom_accent            ||      let == t_bottom_accent
201
 
    );
202
 
}
203
 
 
204
 
INT is_hungar_special(BYTE let)
205
 
{
206
 
return (
207
 
     let == AA_right_accent ||          let == a_right_accent ||
208
 
     let == EE_right_accent ||          let == e_right_accent ||
209
 
     let == II_right_accent ||          let == i_right_accent ||
210
 
     let == OO_right_accent ||          let == o_right_accent ||
211
 
     let == OO_2dot_accent  ||          let == o_2dot_accent  ||
212
 
     let == OO_double_right ||          let == o_double_right
213
 
    );
214
 
}
215
 
 
216
 
INT is_lower(BYTE ch)
217
 
{
218
 
 
219
 
if(language==LANG_RUSSIAN)
220
 
        switch(fEdCode){
221
 
  case ED_ASCII: // for ASCII
222
 
   if((ch >=(BYTE)'�' && ch <=(BYTE)'�') ||
223
 
      (ch >=(BYTE)'�' && ch <=(BYTE)'�') ||
224
 
       memchr("�������",ch,7)
225
 
     ) return 1;
226
 
  break;
227
 
  case ED_WIN: // for Windows (ANSI)
228
 
      if (ch >=0xE0 && ch <=0xFF)
229
 
        return 1;
230
 
  break;
231
 
  case ED_MAC: // for Macintosh
232
 
      if(((ch >=0xE0 && ch <=0xFE) || ch == 0xDF)
233
 
        ) return 1;
234
 
  break;
235
 
        }
236
 
 if(ch >= 'a' && ch <= 'z') return 1;
237
 
 return 0;
238
 
}
239
 
INT is_upper(BYTE ch)
240
 
{
241
 
if(language==LANG_RUSSIAN)
242
 
    switch(fEdCode){
243
 
    case ED_ASCII:
244
 
    case ED_MAC: // for ASCII and Macintosh
245
 
      if(ch >=(BYTE)'�' && ch <=(BYTE)'�'||
246
 
         ch==(BYTE)r_EE_2dot
247
 
        )  return 1;
248
 
    break;
249
 
    case ED_WIN: // for Windows (ANSI)
250
 
      if(ch >= 0xC0 && ch <= 0xDF)
251
 
        return 1;
252
 
    break;
253
 
    }
254
 
if(ch >= 'A' && ch <= 'Z') return 1;
255
 
 return 0;
256
 
}
257
 
 
258
 
BOOL is_digit(BYTE ch)
259
 
{
260
 
if(ch >= (BYTE)'0' && ch <= (BYTE)'9') return TRUE;
261
 
else return FALSE;
262
 
}
263
 
 
264
 
INT isletter(BYTE ch)
265
 
{
266
 
if(is_lower(ch) || is_upper(ch)) return 1;
267
 
else return 0;
268
 
}
269
 
 
270
 
BYTE get_homot(BYTE ch )
271
 
{
272
 
 if(ch == '0') return ((BYTE)'�');
273
 
 if(is_upper(ch)) return to_lower(ch);
274
 
 if(is_lower(ch)) return to_upper(ch);
275
 
 return ch;
276
 
}
277
 
 
278
 
static const BYTE non_twin[]="������";
279
 
static const BYTE lat_twins[]="cCoOpPsSvVwWxXzZ";
280
 
 
281
 
INT twin(BYTE ch)
282
 
{
283
 
if(!isletter(ch)) return 0;
284
 
if( language==LANG_RUSSIAN )
285
 
 if(memchr(non_twin,ch,sizeof non_twin)) return 0;
286
 
 else                                    return 1;
287
 
if( language!=LANG_RUSSIAN && memchr(lat_twins,ch,sizeof lat_twins)) return 1;
288
 
return 0;
 
94
Bool is_liga_ff(uchar c) {
 
95
        // ��� ���� ��������� ����� ����� � ligas.h 05.09.2000 E.P.
 
96
        return (c == liga_ff);
 
97
}
 
98
Bool is_liga_ffl(uchar c) {
 
99
        // ��� ���� ��������� ����� ����� � ligas.h 05.09.2000 E.P.
 
100
        return (c == liga_ffl);
 
101
}
 
102
 
 
103
int16_t is_english(uchar ch) {
 
104
        return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (
 
105
        //         ch>=ligas_beg && ch<=ligas_end &&
 
106
                        is_liga(ch) && // 14.09.2000 E.P.
 
107
 
 
108
                                        ch != liga_exm && ch != liga_qm);
 
109
}
 
110
 
 
111
int16_t is_serbian_special(uchar ch) {
 
112
        return (ch == SERB_j || ch == SERB_J || ch == SERB_n || ch == SERB_N || ch
 
113
                        == SERB_l || ch == SERB_L || ch == SERB_h || ch == SERB_H || ch
 
114
                        == SERB_hh || ch == SERB_HH || ch == SERB_u || ch == SERB_U);
 
115
 
 
116
}
 
117
 
 
118
int16_t is_polish_special(uchar ch) {
 
119
        return (ch == POLISH_SS || ch == POLISH_s || ch == POLISH_ZZD || ch
 
120
                        == POLISH_zd || ch == POLISH_ZZR || ch == POLISH_zr || ch
 
121
                        == POLISH_LL || ch == POLISH_l || ch == POLISH_AA || ch == POLISH_a
 
122
                        || ch == POLISH_CC || ch == POLISH_a || ch == POLISH_NN || ch
 
123
                        == POLISH_n || ch == POLISH_EE || ch == POLISH_e || ch == POLISH_OO
 
124
                        || ch == POLISH_o);
 
125
}
 
126
 
 
127
int16_t is_czech_special(uchar let) {
 
128
        return (let == AA_right_accent || let == a_right_accent || let
 
129
                        == CC_inv_roof || let == c_inv_roof || let == DD_inv_roof || let
 
130
                        == d_inv_roof || let == EE_right_accent || let == e_right_accent
 
131
                        || let == EE_inv_roof || let == e_inv_roof || let
 
132
                        == II_right_accent || let == i_right_accent || let == NN_inv_roof
 
133
                        || let == n_inv_roof || let == OO_right_accent || let
 
134
                        == o_right_accent || let == RR_inv_roof || let == r_inv_roof || let
 
135
                        == SS_inv_roof || let == s_inv_roof || let == TT_inv_roof || let
 
136
                        == t_inv_roof || let == UU_right_accent || let == u_right_accent
 
137
                        || let == UU_circle_accent || let == u_circle_accent || let
 
138
                        == YY_right_accent || let == y_right_accent || let == ZZ_inv_roof
 
139
                        || let == z_inv_roof);
 
140
}
 
141
 
 
142
int16_t is_roman_special(uchar let) {
 
143
        return (let == AA_semicircle || let == a_semicircle || let
 
144
                        == AA_roof_accent || let == a_roof_accent || let == II_roof_accent
 
145
                        || let == i_roof_accent || let == SS_bottom_accent_latin || let
 
146
                        == s_bottom_accent_latin || let == TT_bottom_accent || let
 
147
                        == t_bottom_accent);
 
148
}
 
149
 
 
150
int16_t is_hungar_special(uchar let) {
 
151
        return (let == AA_right_accent || let == a_right_accent || let
 
152
                        == EE_right_accent || let == e_right_accent || let
 
153
                        == II_right_accent || let == i_right_accent || let
 
154
                        == OO_right_accent || let == o_right_accent || let
 
155
                        == OO_2dot_accent || let == o_2dot_accent || let == OO_double_right
 
156
                        || let == o_double_right);
 
157
}
 
158
 
 
159
int16_t is_lower(uchar ch) {
 
160
 
 
161
        if (language == LANG_RUSSIAN)
 
162
                switch (fEdCode) {
 
163
                case ED_ASCII: // for ASCII
 
164
                        if ((ch >= (uchar) '�' && ch <= (uchar) '�') || (ch >= (uchar) '�'
 
165
                                        && ch <= (uchar) '�') || memchr("�������", ch, 7))
 
166
                                return 1;
 
167
                        break;
 
168
                case ED_WIN: // for Windows (ANSI)
 
169
                        if (ch >= 0xE0 && ch <= 0xFF)
 
170
                                return 1;
 
171
                        break;
 
172
                case ED_MAC: // for Macintosh
 
173
                        if (((ch >= 0xE0 && ch <= 0xFE) || ch == 0xDF))
 
174
                                return 1;
 
175
                        break;
 
176
                }
 
177
        if (ch >= 'a' && ch <= 'z')
 
178
                return 1;
 
179
        return 0;
 
180
}
 
181
int16_t is_upper(uchar ch) {
 
182
        if (language == LANG_RUSSIAN)
 
183
                switch (fEdCode) {
 
184
                case ED_ASCII:
 
185
                case ED_MAC: // for ASCII and Macintosh
 
186
                        if (ch >= (uchar) '�' && ch <= (uchar) '�' || ch
 
187
                                        == (uchar) r_EE_2dot)
 
188
                                return 1;
 
189
                        break;
 
190
                case ED_WIN: // for Windows (ANSI)
 
191
                        if (ch >= 0xC0 && ch <= 0xDF)
 
192
                                return 1;
 
193
                        break;
 
194
                }
 
195
        if (ch >= 'A' && ch <= 'Z')
 
196
                return 1;
 
197
        return 0;
 
198
}
 
199
 
 
200
Bool is_digit(uchar ch) {
 
201
        if (ch >= (uchar) '0' && ch <= (uchar) '9')
 
202
                return TRUE;
 
203
        else
 
204
                return FALSE;
 
205
}
 
206
 
 
207
int16_t isletter(uchar ch) {
 
208
        if (is_lower(ch) || is_upper(ch))
 
209
                return 1;
 
210
        else
 
211
                return 0;
 
212
}
 
213
 
 
214
uchar get_homot(uchar ch) {
 
215
        if (ch == '0')
 
216
                return ((uchar) '�');
 
217
        if (is_upper(ch))
 
218
                return to_lower(ch);
 
219
        if (is_lower(ch))
 
220
                return to_upper(ch);
 
221
        return ch;
 
222
}
 
223
 
 
224
static const uchar non_twin[] = "������";
 
225
static const uchar lat_twins[] = "cCoOpPsSvVwWxXzZ";
 
226
 
 
227
int16_t twin(uchar ch) {
 
228
        if (!isletter(ch))
 
229
                return 0;
 
230
        if (language == LANG_RUSSIAN)
 
231
                if (memchr(non_twin, ch, sizeof non_twin))
 
232
                        return 0;
 
233
                else
 
234
                        return 1;
 
235
        if (language != LANG_RUSSIAN && memchr(lat_twins, ch, sizeof lat_twins))
 
236
                return 1;
 
237
        return 0;
289
238
}
290
239
 
291
240
/* Function returns UPPER CASE variant of the letter.             */
292
 
BYTE to_upper( BYTE c )
293
 
{
294
 
  if ( c >= (BYTE)'a' && c <= (BYTE)'z') return c - (BYTE)'a' + (BYTE)'A';
295
 
  if(language==LANG_RUSSIAN)
296
 
       switch(fEdCode){
297
 
  case ED_ASCII:  // for ASCII
298
 
    if ( c >= (BYTE)'�' && c <= (BYTE)'�') return c - (BYTE)'�' + (BYTE)'�';
299
 
    if ( c >= (BYTE)'�' && c <= (BYTE)'�') return c - (BYTE)'�' + (BYTE)'�';
300
 
  break;
301
 
  case ED_WIN: // for Windows (ANSI)
302
 
    if ( c >= 0xE0 && c <= 0xFF ) return c - 0xE0 + 0xC0;
303
 
  break;
304
 
  case ED_MAC: // for Macintosh
305
 
    if ((c >= 0xE0 && c <= 0xFE) ) return c - 0xE0 + 0x80;
306
 
    if ( c == 0xDF )               return 0x9F;
307
 
  break;
308
 
  }
309
 
    return c;
 
241
uchar to_upper(uchar c) {
 
242
        if (c >= (uchar) 'a' && c <= (uchar) 'z')
 
243
                return c - (uchar) 'a' + (uchar) 'A';
 
244
        if (language == LANG_RUSSIAN)
 
245
                switch (fEdCode) {
 
246
                case ED_ASCII: // for ASCII
 
247
                        if (c >= (uchar) '�' && c <= (uchar) '�')
 
248
                                return c - (uchar) '�' + (uchar) '�';
 
249
                        if (c >= (uchar) '�' && c <= (uchar) '�')
 
250
                                return c - (uchar) '�' + (uchar) '�';
 
251
                        break;
 
252
                case ED_WIN: // for Windows (ANSI)
 
253
                        if (c >= 0xE0 && c <= 0xFF)
 
254
                                return c - 0xE0 + 0xC0;
 
255
                        break;
 
256
                case ED_MAC: // for Macintosh
 
257
                        if ((c >= 0xE0 && c <= 0xFE))
 
258
                                return c - 0xE0 + 0x80;
 
259
                        if (c == 0xDF)
 
260
                                return 0x9F;
 
261
                        break;
 
262
                }
 
263
        return c;
310
264
}
311
265
 
312
 
 /* Function returns LOWER CASE variant of the letter.             */
313
 
BYTE to_lower(BYTE c)
314
 
{
315
 
  if ( c >= (BYTE)'A' && c <= (BYTE)'Z') return c - (BYTE)'A'+ (BYTE)'a' ;
316
 
  if(language==LANG_RUSSIAN)
317
 
        switch(fEdCode){
318
 
  case ED_ASCII: // for ASCII
319
 
    if ( c >= (BYTE)'�' && c <= (BYTE)'�') return c - (BYTE)'�'+ (BYTE)'�' ;
320
 
    if ( c >= (BYTE)'�' && c <= (BYTE)'�') return c - (BYTE)'�'+ (BYTE)'�' ;
321
 
  break;
322
 
  case ED_WIN: // for Windows
323
 
    if ( c >= 0xC0 && c <= 0xDF) return c - 0xC0 + 0xE0 ;
324
 
  break;
325
 
  case ED_MAC: // for Macintosh
326
 
    if ( c >= 0x80 && c <= 0x9E) return c - 0x80 + 0xE0 ;
327
 
    if ( c == 0x9F )             return 0xDF;
328
 
  break;
329
 
        }
330
 
    return c;
 
266
/* Function returns LOWER CASE variant of the letter.             */
 
267
uchar to_lower(uchar c) {
 
268
        if (c >= (uchar) 'A' && c <= (uchar) 'Z')
 
269
                return c - (uchar) 'A' + (uchar) 'a';
 
270
        if (language == LANG_RUSSIAN)
 
271
                switch (fEdCode) {
 
272
                case ED_ASCII: // for ASCII
 
273
                        if (c >= (uchar) '�' && c <= (uchar) '�')
 
274
                                return c - (uchar) '�' + (uchar) '�';
 
275
                        if (c >= (uchar) '�' && c <= (uchar) '�')
 
276
                                return c - (uchar) '�' + (uchar) '�';
 
277
                        break;
 
278
                case ED_WIN: // for Windows
 
279
                        if (c >= 0xC0 && c <= 0xDF)
 
280
                                return c - 0xC0 + 0xE0;
 
281
                        break;
 
282
                case ED_MAC: // for Macintosh
 
283
                        if (c >= 0x80 && c <= 0x9E)
 
284
                                return c - 0x80 + 0xE0;
 
285
                        if (c == 0x9F)
 
286
                                return 0xDF;
 
287
                        break;
 
288
                }
 
289
        return c;
331
290
}
332
291
 
333
292
static struct {
334
 
INT     ns1,ns2;
335
 
BYTE    lcase,caps;
 
293
        int16_t ns1, ns2;
 
294
        uchar lcase, caps;
336
295
} lht[128];
337
296
 
338
297
#define v_bs1   1
343
302
// ����� ������������� ��� ���� �����, �.�. � count_line_hi()
344
303
// �� ��� ���� ����� ����� ��������! � ����� ���������� � ���� �������
345
304
// ��������� �� �������� ����� (��� ����� ������ �����������)
346
 
void BaseLineStatisticInit(void)
347
 
{
 
305
void BaseLineStatisticInit(void) {
348
306
        int i;
349
307
 
350
 
        for(i=0; i < arrnum(lht);i++)
351
 
                memset(&lht[i],0,sizeof(lht[0]));  //init
 
308
        for (i = 0; i < arrnum(lht); i++)
 
309
                memset(&lht[i], 0, sizeof(lht[0])); //init
352
310
}
353
311
/////////////////
354
 
INT count_line_hi(void)
355
 
{
356
 
 INT d23[MAX_HEIGHT]={0},
357
 
    d13[MAX_HEIGHT]={0},
358
 
    i,max,index,
359
 
    nbcaps=0,nbsmall=0;
360
 
 CSTR_rast c;
361
 
 CSTR_rast_attr attr;
362
 
 BYTE ch;
363
 
 UniVersions vers;
 
312
int16_t count_line_hi(void) {
 
313
        int16_t d23[MAX_HEIGHT] = { 0 }, d13[MAX_HEIGHT] = { 0 }, i, max, index,
 
314
                        nbcaps = 0, nbsmall = 0;
 
315
        CSTR_rast c;
 
316
        CSTR_rast_attr attr;
 
317
        uchar ch;
 
318
        UniVersions vers;
364
319
 
365
 
        if(line_number >= arrnum(lht))
 
320
        if (line_number >= arrnum(lht))
366
321
                return 0;
367
 
        memset(&lht[line_number],0,sizeof(lht[0]));  //init
 
322
        memset(&lht[line_number], 0, sizeof(lht[0])); //init
368
323
        /* check validate of base 2 and base 3                       */
369
 
        if(!(ncletrs > 6 && ncletrs*2 > ncbs)) // Presentable line ?
370
 
                                      return 0;// NO
 
324
        if (!(ncletrs > 6 && ncletrs * 2 > ncbs)) // Presentable line ?
 
325
                return 0;// NO
371
326
 
372
327
        c = cell_f();
373
328
        //while((c=c->nextl)->nextl != NULL)
374
 
        while((c=CSTR_GetNextRaster(c,CSTR_f_let)) != NULL)
375
 
        {
376
 
    CSTR_GetAttr(c,&attr);
377
 
 
378
 
        if(attr.h <0 || attr.h >= MAX_HEIGHT )
379
 
                continue;
380
 
 
381
 
    CSTR_GetCollectionUni(c,&vers);
382
 
 
383
 
        if(vers.lnAltCnt<=0 || vers.Alt[0].Prob < 140)
384
 
                continue;
385
 
 
386
 
        ch = let_lindef[vers.Alt[0].Liga];
387
 
    if((ch & (v_bs1 | v_bs3)) == (v_bs1 | v_bs3))
388
 
        {
389
 
                d13[attr.h]++;
390
 
                nbcaps++;
391
 
        }
392
 
    if((ch & (v_bs2 | v_bs3)) == (v_bs2 | v_bs3))
393
 
        {
394
 
                d23[attr.h]++;
395
 
                nbsmall++;
396
 
        }
397
 
   }
 
329
        while ((c = CSTR_GetNextRaster(c, CSTR_f_let)) != NULL) {
 
330
                CSTR_GetAttr(c, &attr);
 
331
 
 
332
                if (attr.h < 0 || attr.h >= MAX_HEIGHT)
 
333
                        continue;
 
334
 
 
335
                CSTR_GetCollectionUni(c, &vers);
 
336
 
 
337
                if (vers.lnAltCnt <= 0 || vers.Alt[0].Prob < 140)
 
338
                        continue;
 
339
 
 
340
                ch = let_lindef[vers.Alt[0].Liga];
 
341
                if ((ch & (v_bs1 | v_bs3)) == (v_bs1 | v_bs3)) {
 
342
                        d13[attr.h]++;
 
343
                        nbcaps++;
 
344
                }
 
345
                if ((ch & (v_bs2 | v_bs3)) == (v_bs2 | v_bs3)) {
 
346
                        d23[attr.h]++;
 
347
                        nbsmall++;
 
348
                }
 
349
        }
398
350
 
399
351
        // test - what we got
400
 
 for(i=0,max=0,index=0;i < sizeof(d13)/sizeof(d13[0]);i++)
401
 
 {
402
 
    if(max < d13[i])
403
 
        {
404
 
                max = d13[i]; index = i;
405
 
        }
406
 
 }
407
 
 
408
 
 if( max > 0 )
409
 
         lht[line_number].caps = (BYTE)index;
410
 
 
411
 
 for(i=0,max=0,index=0;i < sizeof(d23)/sizeof(d23[0]);i++)
412
 
 {
413
 
    if(max < d23[i])
414
 
        {
415
 
                max = d23[i]; index = i;
416
 
        }
417
 
 }
418
 
 
419
 
 if( max > 0 ) lht[line_number].lcase = (BYTE)index;
420
 
 
421
 
 lht[line_number].ns1 = nbcaps;
422
 
 lht[line_number].ns2 = nbsmall;
423
 
 
424
 
 return (lht[line_number].caps  != 0 ||
425
 
        lht[line_number].lcase != 0 ); /* if there some information */
 
352
        for (i = 0, max = 0, index = 0; i < sizeof(d13) / sizeof(d13[0]); i++) {
 
353
                if (max < d13[i]) {
 
354
                        max = d13[i];
 
355
                        index = i;
 
356
                }
 
357
        }
 
358
 
 
359
        if (max > 0)
 
360
                lht[line_number].caps = (uchar) index;
 
361
 
 
362
        for (i = 0, max = 0, index = 0; i < sizeof(d23) / sizeof(d23[0]); i++) {
 
363
                if (max < d23[i]) {
 
364
                        max = d23[i];
 
365
                        index = i;
 
366
                }
 
367
        }
 
368
 
 
369
        if (max > 0)
 
370
                lht[line_number].lcase = (uchar) index;
 
371
 
 
372
        lht[line_number].ns1 = nbcaps;
 
373
        lht[line_number].ns2 = nbsmall;
 
374
 
 
375
        return (lht[line_number].caps != 0 || lht[line_number].lcase != 0); /* if there some information */
426
376
}
427
377
 
428
378
/* Return  most usable height in line */
429
 
INT h_hist(void)
430
 
{
431
 
 CSTR_rast c;
432
 
 CSTR_rast_attr attr;
433
 
 INT h[MAX_HEIGHT]={0},th[MAX_HEIGHT]={0},
434
 
    i,max,index,
435
 
    recognized=0,total=0;
436
 
 BYTE ch;
437
 
 UniVersions vers;
438
 
 
439
 
 c = cell_f();
440
 
// while((c=c->nextl)->nextl != NULL)
441
 
 while((c=CSTR_GetNextRaster(c,f_letter)) != NULL)
442
 
 {
443
 
    CSTR_GetAttr(c,&attr);
444
 
        if(attr.h <0 || attr.h >= MAX_HEIGHT )
445
 
                continue;
446
 
 
447
 
    total++;
448
 
    th[attr.h]++; // all over
449
 
 
450
 
    CSTR_GetCollectionUni(c,&vers);
451
 
 
452
 
//      if(!(c->flg & CSTR_f_let))continue;
453
 
        if( !(attr.flg & CSTR_f_let ) ||  vers.lnAltCnt<=0 )
454
 
                continue;
455
 
 
456
 
        ch = let_lindef[vers.Alt[0].Liga];
457
 
    if((ch & v_bs3) && ((ch & v_bs1) || (ch & v_bs2)))
458
 
    {
459
 
           recognized++;
460
 
           h[attr.h]++;
461
 
        }
462
 
 }
463
 
 
464
 
  if(recognized > 3 || recognized*2 > total)
465
 
  {
466
 
   for(i=0,max=0,index=0;i < sizeof(h)/sizeof(h[0]);i++)
467
 
   {
468
 
    if(max < h[i])
469
 
        {
470
 
                max = h[i]; index = i;
471
 
        }
472
 
   }
473
 
 
474
 
   max*=2;
475
 
   max+=h[index-1]*2;
476
 
   max+=h[index+1]*2;
477
 
   max+=h[index+2];
478
 
   max+=h[index-2];
479
 
   max/=2;
480
 
 
481
 
   if(recognized > 4 )
482
 
   {  // letters have the same height
483
 
    if( max*4 >= recognized*3 ) return index;
484
 
   }
485
 
   else return index;
486
 
  }
487
 
 
488
 
  else if(recognized < 4 && total > 4 )
489
 
  {
490
 
   for(i=0,max=0,index=0;i < sizeof(th)/sizeof(th[0]);i++)
491
 
   {
492
 
    if(max < th[i])
493
 
        {
494
 
                max = th[i]; index = i;
495
 
        }
496
 
   }
497
 
 
498
 
   max*=2;
499
 
   max+=th[index-1]*2;
500
 
   max+=th[index+1]*2;
501
 
   max+=th[index+2];
502
 
   max+=th[index-2];
503
 
   max/=2;
504
 
   if(max*2 > total ) return index; // letters have the same height
505
 
  }
506
 
 
507
 
  for(i=0,max=0,index=0;i < sizeof(th)/sizeof(th[0]);i++)
508
 
  {
509
 
    if(max < th[i])
510
 
        {
511
 
                max = th[i]; index = i;
512
 
        }
513
 
  }
514
 
 
515
 
  if(max+th[index+1]+th[index-1] == total )
516
 
          return index;
517
 
 
518
 
  return 0;
 
379
int16_t h_hist(void) {
 
380
        CSTR_rast c;
 
381
        CSTR_rast_attr attr;
 
382
        int16_t h[MAX_HEIGHT] = { 0 }, th[MAX_HEIGHT] = { 0 }, i, max, index,
 
383
                        recognized = 0, total = 0;
 
384
        uchar ch;
 
385
        UniVersions vers;
 
386
 
 
387
        c = cell_f();
 
388
        // while((c=c->nextl)->nextl != NULL)
 
389
        while ((c = CSTR_GetNextRaster(c, f_letter)) != NULL) {
 
390
                CSTR_GetAttr(c, &attr);
 
391
                if (attr.h < 0 || attr.h >= MAX_HEIGHT)
 
392
                        continue;
 
393
 
 
394
                total++;
 
395
                th[attr.h]++; // all over
 
396
 
 
397
                CSTR_GetCollectionUni(c, &vers);
 
398
 
 
399
                //      if(!(c->flg & CSTR_f_let))continue;
 
400
                if (!(attr.flg & CSTR_f_let) || vers.lnAltCnt <= 0)
 
401
                        continue;
 
402
 
 
403
                ch = let_lindef[vers.Alt[0].Liga];
 
404
                if ((ch & v_bs3) && ((ch & v_bs1) || (ch & v_bs2))) {
 
405
                        recognized++;
 
406
                        h[attr.h]++;
 
407
                }
 
408
        }
 
409
 
 
410
        if (recognized > 3 || recognized * 2 > total) {
 
411
                for (i = 0, max = 0, index = 0; i < sizeof(h) / sizeof(h[0]); i++) {
 
412
                        if (max < h[i]) {
 
413
                                max = h[i];
 
414
                                index = i;
 
415
                        }
 
416
                }
 
417
 
 
418
                max *= 2;
 
419
                max += h[index - 1] * 2;
 
420
                max += h[index + 1] * 2;
 
421
                max += h[index + 2];
 
422
                max += h[index - 2];
 
423
                max /= 2;
 
424
 
 
425
                if (recognized > 4) { // letters have the same height
 
426
                        if (max * 4 >= recognized * 3)
 
427
                                return index;
 
428
                } else
 
429
                        return index;
 
430
        }
 
431
 
 
432
        else if (recognized < 4 && total > 4) {
 
433
                for (i = 0, max = 0, index = 0; i < sizeof(th) / sizeof(th[0]); i++) {
 
434
                        if (max < th[i]) {
 
435
                                max = th[i];
 
436
                                index = i;
 
437
                        }
 
438
                }
 
439
 
 
440
                max *= 2;
 
441
                max += th[index - 1] * 2;
 
442
                max += th[index + 1] * 2;
 
443
                max += th[index + 2];
 
444
                max += th[index - 2];
 
445
                max /= 2;
 
446
                if (max * 2 > total)
 
447
                        return index; // letters have the same height
 
448
        }
 
449
 
 
450
        for (i = 0, max = 0, index = 0; i < sizeof(th) / sizeof(th[0]); i++) {
 
451
                if (max < th[i]) {
 
452
                        max = th[i];
 
453
                        index = i;
 
454
                }
 
455
        }
 
456
 
 
457
        if (max + th[index + 1] + th[index - 1] == total)
 
458
                return index;
 
459
 
 
460
        return 0;
519
461
}
520
462
/*---------------------------------------
521
463
 * Return:      0 - can't set case      *
522
464
 *              1 - base line 1         *
523
465
 *              2 - base line 2         *
524
466
 *--------------------------------------*/
525
 
BYTE page_stat,stable_b3;
526
 
 
527
 
INT setup_let_case(INT ckH)
528
 
{
529
 
INT i,umax,lmax,lh,uprob,lprob,ret=0;
530
 
INT uc[MAX_HEIGHT]={0},
531
 
    lc[MAX_HEIGHT]={0};
532
 
 
533
 
 // Nick 26.01.2000  - � �������� ����� ���� ����� ������� ������ �����!
534
 
 int lastLineNumber = MIN(sizeof(lht)/sizeof(lht[0]), line_number );
535
 
 int firLineNumber = 1;  // � ��� ��� ����� 0
536
 
 
537
 
      page_stat=0;
538
 
 //if(line_number < 2) return 0;
539
 
 if(ckH) lh=ckH;
540
 
 else
541
 
 if((lh = h_hist()) == 0) return 0;
542
 
 
543
 
 for(i=firLineNumber;i < line_number && i < sizeof(lht)/sizeof(lht[0]);i++)
544
 
 {
545
 
  uc[MIN(lht[i].caps,MAX_HEIGHT-1)]++; /* Calc histogram */
546
 
  lc[MIN(lht[i].lcase,MAX_HEIGHT-1)]++; // Nick 25.05.2001
547
 
 }
548
 
 
549
 
 umax  = uc[lh]+uc[lh+1]+uc[lh-1]+uc[lh+2]+uc[lh-2];
550
 
 lmax  = lc[lh]+lc[lh+1]+lc[lh-1];
551
 
 
552
 
 for(i=firLineNumber, lprob=0;i < lastLineNumber;i++)  // Nick 26.01.2001 - was line_number
553
 
   if( abs(lht[i].lcase-lh) < 3 )lprob += lht[i].ns2;
554
 
 for(i=firLineNumber, uprob=0;i < lastLineNumber;i++)  // Nick 26.01.2001 - was line_number
555
 
 {
556
 
   if( abs(lht[i].caps-lh) < 3 )
557
 
           uprob += lht[i].ns1;
558
 
 }
559
 
 
560
 
 if(lmax >= umax && lmax > 0)
561
 
 {
562
 
         ret=2; if(!ckH) page_stat=1;
563
 
 }
564
 
 if(umax >  lmax && umax > 0)
565
 
 {
566
 
         ret=1; if(!ckH) page_stat=1;
567
 
 }
568
 
 if(db_status & snap_activity_rbal(db_pass) && ret!=0)
569
 
 {
570
 
  CHAR buf[120];
571
 
  sprintf(buf,"Page statistic lh=%u  caps=%u,%u lcase=%u,%u ",lh,umax,uprob,lmax,lprob);
572
 
  snap_show_text_rbal(buf); snap_monitor_rbal();
573
 
 }
574
 
return ret;
 
467
uchar page_stat, stable_b3;
 
468
 
 
469
int16_t setup_let_case(int16_t ckH) {
 
470
        int16_t i, umax, lmax, lh, uprob, lprob, ret = 0;
 
471
        int16_t uc[MAX_HEIGHT] = { 0 }, lc[MAX_HEIGHT] = { 0 };
 
472
 
 
473
        // Nick 26.01.2000  - � �������� ����� ���� ����� ������� ������ �����!
 
474
        int lastLineNumber = MIN(sizeof(lht) / sizeof(lht[0]), line_number);
 
475
        int firLineNumber = 1; // � ��� ��� ����� 0
 
476
 
 
477
        page_stat = 0;
 
478
        //if(line_number < 2) return 0;
 
479
        if (ckH)
 
480
                lh = ckH;
 
481
        else if ((lh = h_hist()) == 0)
 
482
                return 0;
 
483
 
 
484
        for (i = firLineNumber; i < line_number && i < sizeof(lht) / sizeof(lht[0]); i++) {
 
485
                uc[MIN(lht[i].caps, MAX_HEIGHT - 1)]++; /* Calc histogram */
 
486
                lc[MIN(lht[i].lcase, MAX_HEIGHT - 1)]++; // Nick 25.05.2001
 
487
        }
 
488
 
 
489
        umax = uc[lh] + uc[lh + 1] + uc[lh - 1] + uc[lh + 2] + uc[lh - 2];
 
490
        lmax = lc[lh] + lc[lh + 1] + lc[lh - 1];
 
491
 
 
492
        for (i = firLineNumber, lprob = 0; i < lastLineNumber; i++) // Nick 26.01.2001 - was line_number
 
493
                if (abs(lht[i].lcase - lh) < 3)
 
494
                        lprob += lht[i].ns2;
 
495
        for (i = firLineNumber, uprob = 0; i < lastLineNumber; i++) // Nick 26.01.2001 - was line_number
 
496
        {
 
497
                if (abs(lht[i].caps - lh) < 3)
 
498
                        uprob += lht[i].ns1;
 
499
        }
 
500
 
 
501
        if (lmax >= umax && lmax > 0) {
 
502
                ret = 2;
 
503
                if (!ckH)
 
504
                        page_stat = 1;
 
505
        }
 
506
        if (umax > lmax && umax > 0) {
 
507
                ret = 1;
 
508
                if (!ckH)
 
509
                        page_stat = 1;
 
510
        }
 
511
        if (db_status & snap_activity_rbal(db_pass) && ret != 0) {
 
512
                char buf[120];
 
513
                sprintf(buf, "Page statistic lh=%u  caps=%u,%u lcase=%u,%u ", lh, umax,
 
514
                                uprob, lmax, lprob);
 
515
                snap_show_text_rbal(buf);
 
516
                snap_monitor_rbal();
 
517
        }
 
518
        return ret;
575
519
}
576
520
 
577
 
 
578
521
/********************************************************
579
522
 *                                                      *
580
523
 *      Func walk by string tries to discrim  some      *
582
525
 *      Only for russian language.                      *
583
526
 ********************************************************/
584
527
 
585
 
INT draft_cut_hyps(INT bs,INT flag)
586
 
{
587
 
CSTR_rast c;
588
 
CSTR_rast_attr attr;
589
 
//version * v;
590
 
UniVersions vers;
591
 
int i;
592
 
BYTE ldef,let,gtwin=0;
593
 
INT dist,cutting_made=0,diff;
594
 
 
595
 
 c = cell_f();
596
 
 
597
 
 if( flag ) // add homotetia  versions
598
 
 {
599
 
//  while ((c=c->nextl)->nextl)
600
 
  while ((c=CSTR_GetNextRaster(c,CSTR_f_let)) )
601
 
  {
602
 
   CSTR_GetCollectionUni(c,&vers);
603
 
   let = vers.Alt[0].Liga;
604
 
//   if(!(c->flg & CSTR_f_let) || !isletter(let))
605
 
   if( vers.lnAltCnt<=0 || !isletter(let) )
606
 
           continue;
607
 
 
608
 
   if(!twin(let))
609
 
           continue;
610
 
   let = is_lower(let) ? to_upper(let) : to_lower(let);
611
 
   promote(0,c,let,0); // insvers
612
 
 
613
 
//   c->vers[c->nvers].let=c->vers[c->nvers].prob=0;
614
 
  }
615
 
 }
616
 
 
617
 
 c = cell_f();
618
 
 if(bs == 3) // cut hyps by bb3
619
 
 {
620
 
  while ((c=CSTR_GetNextRaster(c,CSTR_f_let)))
621
 
  {
622
 
//   if(!(c->flg & CSTR_f_let)) continue;
623
 
   CSTR_GetAttr(c,&attr);
624
 
   dist = 0;
625
 
   diff = 0;
626
 
   if( attr.bdiff!=127 )
627
 
           diff=attr.bdiff;
628
 
 
629
 
   CSTR_GetCollectionUni(c,&vers);
630
 
 
631
 
//   for (v=c->vers; (let=v->let) != 0; v++)
632
 
   for(i=0;i<vers.lnAltCnt;i++)
633
 
   {
634
 
    dist = abs((attr.row + attr.h) - ( minrow + bbs3 + diff )); // Is it far from bbs3
635
 
        let = vers.Alt[i].Liga;
636
 
 
637
 
    ldef = let_linpos[let] & 0x0f;
638
 
    if(memchr("���",let,3))
639
 
                continue; // don't discrim
640
 
    if(memchr("����",let,4))
641
 
                gtwin = 1;
642
 
 
643
 
    if(ldef == 2) // Is it sunk letter
644
 
        {
645
 
     if(dist < 3)
646
 
         {  // Yes try to discrim
647
 
      //v->prob |= 1; // Exclude from statistic by base line detection
648
 
      vers.Alt[i].Prob |= 1;
649
 
      cutting_made = 1;
650
 
         }
651
 
        }
652
 
    if(ldef & 1 && ldef != 7) // Is it lay on bs3 don't touch �,�,�
653
 
        {
654
 
     if(dist > 2)
655
 
         { // Yes try to discrim
656
 
      //v->prob |= 1;
657
 
          vers.Alt[i].Prob |= 1;
658
 
      cutting_made = 1;
659
 
         }
660
 
    }
661
 
 
662
 
   }  // loop by hyps
663
 
 
664
 
   CSTR_StoreCollectionUni(c,&vers);
665
 
 
666
 
  }       // loop by string
667
 
 }  // end if bs == 3
668
 
 
669
 
 c = cell_f();
670
 
 if(bs == 2)
671
 
 {
672
 
//  while ((c=c->nextl)->nextl)
673
 
  while ((c=CSTR_GetNextRaster(c,CSTR_f_let)))
674
 
  {
675
 
// if(!(c->flg & CSTR_f_let)) continue;
676
 
   CSTR_GetAttr(c,&attr);
677
 
   CSTR_GetCollectionUni(c,&vers);
678
 
 
679
 
//   for (v=c->vers; (let=v->let) != 0; v++)
680
 
   for(i=0;i<vers.lnAltCnt;i++)
681
 
   {
682
 
           let = vers.Alt[i].Liga;
683
 
 
684
 
           ldef = let_linpos[let] >> 4;
685
 
           dist = (bbs3-Ps) - (attr.row-minrow);
686
 
 
687
 
       if( (ldef & 2)==2 && dist>3)
688
 
           { // Is it letter lay on bb2
689
 
        //v->prob |= 1; // Exclude from statistic by base line detection
690
 
        vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
691
 
        cutting_made = 1;
692
 
       }
693
 
 
694
 
       if( ldef & 1 && dist <= 3 )  // capital
695
 
           {
696
 
        //v->prob |= 1;
697
 
                vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
698
 
        cutting_made = 1;
699
 
           }
700
 
 
701
 
   }  // loop by hyps
702
 
 
703
 
   CSTR_StoreCollectionUni(c,&vers);
704
 
 
705
 
  }       // loop by string
706
 
 }
707
 
 
708
 
 if(bs == 1)
709
 
 {
710
 
  while ((c=CSTR_GetNextRaster(c,CSTR_f_let)))
711
 
  {
712
 
// if(!(c->flg & CSTR_f_let)) continue;
713
 
   CSTR_GetAttr(c,&attr);
714
 
   CSTR_GetCollectionUni(c,&vers);
715
 
 
716
 
//   for (v=c->vers; (let=v->let) != 0; v++)
717
 
   for(i=0;i<vers.lnAltCnt;i++)
718
 
   {
719
 
           let = vers.Alt[i].Liga;
720
 
       ldef = let_linpos[let] >> 4;
721
 
       dist=(bbs3-Ps)-(attr.row-minrow);
722
 
       if(ldef & 1 && dist<=3) // Is it lay near bb2
723
 
           {
724
 
        //v->prob |= 1; // Exclude from statistic by base line detection
725
 
        vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
726
 
        cutting_made = 1;
727
 
           }
728
 
       if( (ldef & 2)==2 && dist<=3 )  // small
729
 
           {
730
 
        //v->prob |= 1;
731
 
        vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
732
 
        cutting_made = 1;
733
 
           }
734
 
 
735
 
   }  // loop by hyps
736
 
 
737
 
   CSTR_StoreCollectionUni(c,&vers);
738
 
 
739
 
  }       // loop by string
740
 
 }  // end if
741
 
 
742
 
 return (cutting_made || gtwin);
 
528
int16_t draft_cut_hyps(int16_t bs, int16_t flag) {
 
529
        CSTR_rast c;
 
530
        CSTR_rast_attr attr;
 
531
        //version * v;
 
532
        UniVersions vers;
 
533
        int i;
 
534
        uchar ldef, let, gtwin = 0;
 
535
        int16_t dist, cutting_made = 0, diff;
 
536
 
 
537
        c = cell_f();
 
538
 
 
539
        if (flag) // add homotetia  versions
 
540
        {
 
541
                //  while ((c=c->nextl)->nextl)
 
542
                while ((c = CSTR_GetNextRaster(c, CSTR_f_let))) {
 
543
                        CSTR_GetCollectionUni(c, &vers);
 
544
                        let = vers.Alt[0].Liga;
 
545
                        //   if(!(c->flg & CSTR_f_let) || !isletter(let))
 
546
                        if (vers.lnAltCnt <= 0 || !isletter(let))
 
547
                                continue;
 
548
 
 
549
                        if (!twin(let))
 
550
                                continue;
 
551
                        let = is_lower(let) ? to_upper(let) : to_lower(let);
 
552
                        promote(0, c, let, 0); // insvers
 
553
 
 
554
                        //   c->vers[c->nvers].let=c->vers[c->nvers].prob=0;
 
555
                }
 
556
        }
 
557
 
 
558
        c = cell_f();
 
559
        if (bs == 3) // cut hyps by bb3
 
560
        {
 
561
                while ((c = CSTR_GetNextRaster(c, CSTR_f_let))) {
 
562
                        //   if(!(c->flg & CSTR_f_let)) continue;
 
563
                        CSTR_GetAttr(c, &attr);
 
564
                        dist = 0;
 
565
                        diff = 0;
 
566
                        if (attr.bdiff != 127)
 
567
                                diff = attr.bdiff;
 
568
 
 
569
                        CSTR_GetCollectionUni(c, &vers);
 
570
 
 
571
                        //   for (v=c->vers; (let=v->let) != 0; v++)
 
572
                        for (i = 0; i < vers.lnAltCnt; i++) {
 
573
                                dist = abs((attr.row + attr.h) - (minrow + bbs3 + diff)); // Is it far from bbs3
 
574
                                let = vers.Alt[i].Liga;
 
575
 
 
576
                                ldef = let_linpos[let] & 0x0f;
 
577
                                if (memchr("���", let, 3))
 
578
                                        continue; // don't discrim
 
579
                                if (memchr("����", let, 4))
 
580
                                        gtwin = 1;
 
581
 
 
582
                                if (ldef == 2) // Is it sunk letter
 
583
                                {
 
584
                                        if (dist < 3) { // Yes try to discrim
 
585
                                                //v->prob |= 1; // Exclude from statistic by base line detection
 
586
                                                vers.Alt[i].Prob |= 1;
 
587
                                                cutting_made = 1;
 
588
                                        }
 
589
                                }
 
590
                                if (ldef & 1 && ldef != 7) // Is it lay on bs3 don't touch �,�,�
 
591
                                {
 
592
                                        if (dist > 2) { // Yes try to discrim
 
593
                                                //v->prob |= 1;
 
594
                                                vers.Alt[i].Prob |= 1;
 
595
                                                cutting_made = 1;
 
596
                                        }
 
597
                                }
 
598
 
 
599
                        } // loop by hyps
 
600
 
 
601
                        CSTR_StoreCollectionUni(c, &vers);
 
602
 
 
603
                } // loop by string
 
604
        } // end if bs == 3
 
605
 
 
606
        c = cell_f();
 
607
        if (bs == 2) {
 
608
                //  while ((c=c->nextl)->nextl)
 
609
                while ((c = CSTR_GetNextRaster(c, CSTR_f_let))) {
 
610
                        // if(!(c->flg & CSTR_f_let)) continue;
 
611
                        CSTR_GetAttr(c, &attr);
 
612
                        CSTR_GetCollectionUni(c, &vers);
 
613
 
 
614
                        //   for (v=c->vers; (let=v->let) != 0; v++)
 
615
                        for (i = 0; i < vers.lnAltCnt; i++) {
 
616
                                let = vers.Alt[i].Liga;
 
617
 
 
618
                                ldef = let_linpos[let] >> 4;
 
619
                                dist = (bbs3 - Ps) - (attr.row - minrow);
 
620
 
 
621
                                if ((ldef & 2) == 2 && dist > 3) { // Is it letter lay on bb2
 
622
                                        //v->prob |= 1; // Exclude from statistic by base line detection
 
623
                                        vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
 
624
                                        cutting_made = 1;
 
625
                                }
 
626
 
 
627
                                if (ldef & 1 && dist <= 3) // capital
 
628
                                {
 
629
                                        //v->prob |= 1;
 
630
                                        vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
 
631
                                        cutting_made = 1;
 
632
                                }
 
633
 
 
634
                        } // loop by hyps
 
635
 
 
636
                        CSTR_StoreCollectionUni(c, &vers);
 
637
 
 
638
                } // loop by string
 
639
        }
 
640
 
 
641
        if (bs == 1) {
 
642
                while ((c = CSTR_GetNextRaster(c, CSTR_f_let))) {
 
643
                        // if(!(c->flg & CSTR_f_let)) continue;
 
644
                        CSTR_GetAttr(c, &attr);
 
645
                        CSTR_GetCollectionUni(c, &vers);
 
646
 
 
647
                        //   for (v=c->vers; (let=v->let) != 0; v++)
 
648
                        for (i = 0; i < vers.lnAltCnt; i++) {
 
649
                                let = vers.Alt[i].Liga;
 
650
                                ldef = let_linpos[let] >> 4;
 
651
                                dist = (bbs3 - Ps) - (attr.row - minrow);
 
652
                                if (ldef & 1 && dist <= 3) // Is it lay near bb2
 
653
                                {
 
654
                                        //v->prob |= 1; // Exclude from statistic by base line detection
 
655
                                        vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
 
656
                                        cutting_made = 1;
 
657
                                }
 
658
                                if ((ldef & 2) == 2 && dist <= 3) // small
 
659
                                {
 
660
                                        //v->prob |= 1;
 
661
                                        vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
 
662
                                        cutting_made = 1;
 
663
                                }
 
664
 
 
665
                        } // loop by hyps
 
666
 
 
667
                        CSTR_StoreCollectionUni(c, &vers);
 
668
 
 
669
                } // loop by string
 
670
        } // end if
 
671
 
 
672
        return (cutting_made || gtwin);
743
673
}
744
674
/////////////
745
 
extern BYTE disable_twins;
746
 
extern INT it_done;
747
 
 
748
 
void set_rus_difflg(CSTR_rast B1, INT filter)
749
 
{
750
 
  //CSTR_comp *env;
751
 
  CCOM_comp *env;
752
 
  CSTR_rast_attr attr;
753
 
 
754
 
  BYTE let, tbe, tshp;
755
 
  BYTE fl1, fl2, fl2t, flt, flnt, fl_cut, fl_retain;
756
 
//  version *v0;
757
 
  UniVersions vers;
758
 
  int i;
759
 
  BYTE cap_shape,solid,notwins;
760
 
 
761
 
  fl_cut = filter & f_cut;
762
 
  fl_retain = filter & f_retain;
763
 
  fl1=0xff;                           // all lines defined
764
 
  fl2=fl2t=0;
765
 
  solid=0;
766
 
  notwins=disable_twins == 1 ? 1 : 0;
767
 
  flt=0;
768
 
  flnt = 0;     // 't' only
769
 
 
770
 
//  env=B1->env;
771
 
  env = CSTR_GetComp(B1);
772
 
 
773
 
  cap_shape = 1;     // capital in shape
774
 
 
775
 
  CSTR_GetAttr(B1,&attr);
776
 
  CSTR_GetCollectionUni(B1,&vers);
777
 
 
778
 
//  for (v0=B1->vers; (let=v0->let) != 0; v0++)
779
 
  for(i=0;i<vers.lnAltCnt;i++)
780
 
  {
781
 
   /*
782
 
    if( v0->prob & 1){
783
 
     v0->prob &= 0xfe; continue;  // clear cut flag
784
 
    }
785
 
   */
786
 
    let = vers.Alt[i].Liga;
787
 
 
788
 
    tbe  = let_lindef[let];
789
 
    tshp = let_linshape[let];
790
 
    cap_shape &= tshp;
791
 
 
792
 
// Nick - check ?
793
 
    solid += tbe < 32; // is it letter without twins
794
 
    flnt = 1;
795
 
 
796
 
    if (env->large & CCOM_LR_UNDERLINED)
797
 
        {
798
 
      if (tshp & 2)        // sticky in shape
799
 
        { fl1=0; break; }  // no lines defined
800
 
        }
801
 
 
802
 
    fl2t |= tbe;  // accumulate b1/b2
803
 
 
804
 
    //if (v0->prob & 1)     // cutten version
805
 
        if (vers.Alt[i].Prob & 1)     // cutten version
806
 
      continue;
807
 
 
808
 
    if( disable_twins == 2)
809
 
        {
810
 
     if( memchr("����",let,4))
811
 
                 notwins = 1;
812
 
        }
813
 
 
814
 
    fl2 |= tbe;  // accumulate b1/b2
815
 
 
816
 
    if (tshp & 4)    // stick allows to define bs1 ( iI1l )
817
 
    {
818
 
        if (oNb2 > 3)   // base 2 defined
819
 
        {
820
 
          if (attr.h > (oPs + 3))
821
 
            { tbe |= 1; }    // allow to def bs1
822
 
        }
823
 
        else
824
 
          tbe &= 0xf4;
825
 
 
826
 
      // retain only b3 line for sticks while dusts not present
827
 
      #ifdef UFA
828
 
       fl1=0xff; break; // stick can't define any bases
829
 
      #endif
830
 
    }
831
 
 
832
 
    fl1 &= tbe;
833
 
 
834
 
    if( lin_pass == 3 &&
835
 
//              v0 == B1->vers && B1->nvers > 1 &&
836
 
        i == 0 && vers.lnAltCnt > 1 &&
837
 
//       (v0->prob - (v0+1)->prob) > 60 &&
838
 
        vers.Alt[i].Prob- vers.Alt[i+1].Prob > 60 &&
839
 
        !twin(let) &&
840
 
            ( attr.recsource & CSTR_rs_BOX )
841
 
     )
842
 
    break; //
843
 
  }  // FOR versions
844
 
 
845
 
  if((notwins || it_done) && fl1 != 0xff )
846
 
  {
847
 
   fl1 &=(BYTE)~c_df_twins;
848
 
   fl2 &=(BYTE)~c_df_twins;
849
 
  }
850
 
 
851
 
  attr.difflg &= fl_retain;
852
 
 
853
 
  if (fl1 != 0xff)     // some bases defined
854
 
  {
855
 
     attr.basflg = flt;  // agree to 't' type
856
 
     if (fl1 & c_df_round)
857
 
       attr.basflg |= CSTR_bs_round;
858
 
     if (cap_shape)
859
 
       attr.basflg |= CSTR_bs_cap;
860
 
     if (fl2 & c_df_twins)    // a non_cutten version had a twin
861
 
     {
862
 
       if ((fl2t & (CSTR_db_b1 | CSTR_db_b2)) != (CSTR_db_b1 | CSTR_db_b2))
863
 
       //  b1 or b2  were absent in full list
864
 
       {
865
 
         fl1 &= ~(CSTR_db_b1 | CSTR_db_b2);   // forget b1/b2 as defined
866
 
         if( attr.bas_acc & CSTR_ba_chance ) // gleb
867
 
           attr.basflg |= (CSTR_bs_b1a | CSTR_bs_b2a); // agrees to be both b1. b2
868
 
       }
869
 
      if( disable_twins == 0 && fl1 & CSTR_db_b4)
870
 
                  fl1 &=~CSTR_db_b4;
871
 
     }
872
 
     if (fl2 & (CSTR_db_b1 | c_df_b1a))
873
 
       attr.basflg |= CSTR_bs_b1a;
874
 
     if (fl2 & (CSTR_db_b2 | c_df_b2a))
875
 
       attr.basflg |= CSTR_bs_b2a;
876
 
     attr.difflg = attr.difflg | (fl1 & 15);
877
 
     if (flnt==0)
878
 
                 attr.basflg |= CSTR_bs_t;  // no "not a 't'" version
879
 
  }
880
 
 
881
 
  CSTR_SetAttr(B1,&attr);
 
675
extern uchar disable_twins;
 
676
extern int16_t it_done;
 
677
 
 
678
void set_rus_difflg(CSTR_rast B1, int16_t filter) {
 
679
        //CSTR_comp *env;
 
680
        CCOM_comp *env;
 
681
        CSTR_rast_attr attr;
 
682
 
 
683
        uchar let, tbe, tshp;
 
684
        uchar fl1, fl2, fl2t, flt, flnt, fl_cut, fl_retain;
 
685
        //  version *v0;
 
686
        UniVersions vers;
 
687
        int i;
 
688
        uchar cap_shape, solid, notwins;
 
689
 
 
690
        fl_cut = filter & f_cut;
 
691
        fl_retain = filter & f_retain;
 
692
        fl1 = 0xff; // all lines defined
 
693
        fl2 = fl2t = 0;
 
694
        solid = 0;
 
695
        notwins = disable_twins == 1 ? 1 : 0;
 
696
        flt = 0;
 
697
        flnt = 0; // 't' only
 
698
 
 
699
        //  env=B1->env;
 
700
        env = CSTR_GetComp(B1);
 
701
 
 
702
        cap_shape = 1; // capital in shape
 
703
 
 
704
        CSTR_GetAttr(B1, &attr);
 
705
        CSTR_GetCollectionUni(B1, &vers);
 
706
 
 
707
        //  for (v0=B1->vers; (let=v0->let) != 0; v0++)
 
708
        for (i = 0; i < vers.lnAltCnt; i++) {
 
709
                /*
 
710
                 if( v0->prob & 1){
 
711
                 v0->prob &= 0xfe; continue;  // clear cut flag
 
712
                 }
 
713
                 */
 
714
                let = vers.Alt[i].Liga;
 
715
 
 
716
                tbe = let_lindef[let];
 
717
                tshp = let_linshape[let];
 
718
                cap_shape &= tshp;
 
719
 
 
720
                // Nick - check ?
 
721
                solid += tbe < 32; // is it letter without twins
 
722
                flnt = 1;
 
723
 
 
724
                if (env->large & CCOM_LR_UNDERLINED) {
 
725
                        if (tshp & 2) // sticky in shape
 
726
                        {
 
727
                                fl1 = 0;
 
728
                                break;
 
729
                        } // no lines defined
 
730
                }
 
731
 
 
732
                fl2t |= tbe; // accumulate b1/b2
 
733
 
 
734
                //if (v0->prob & 1)     // cutten version
 
735
                if (vers.Alt[i].Prob & 1) // cutten version
 
736
                        continue;
 
737
 
 
738
                if (disable_twins == 2) {
 
739
                        if (memchr("����", let, 4))
 
740
                                notwins = 1;
 
741
                }
 
742
 
 
743
                fl2 |= tbe; // accumulate b1/b2
 
744
 
 
745
                if (tshp & 4) // stick allows to define bs1 ( iI1l )
 
746
                {
 
747
                        if (oNb2 > 3) // base 2 defined
 
748
                        {
 
749
                                if (attr.h > (oPs + 3)) {
 
750
                                        tbe |= 1;
 
751
                                } // allow to def bs1
 
752
                        } else
 
753
                                tbe &= 0xf4;
 
754
 
 
755
                        // retain only b3 line for sticks while dusts not present
 
756
#ifdef UFA
 
757
                        fl1=0xff; break; // stick can't define any bases
 
758
#endif
 
759
                }
 
760
 
 
761
                fl1 &= tbe;
 
762
 
 
763
                if (lin_pass == 3 &&
 
764
                //              v0 == B1->vers && B1->nvers > 1 &&
 
765
                                i == 0 && vers.lnAltCnt > 1 &&
 
766
                //       (v0->prob - (v0+1)->prob) > 60 &&
 
767
                                vers.Alt[i].Prob - vers.Alt[i + 1].Prob > 60 && !twin(let)
 
768
                                && (attr.recsource & CSTR_rs_BOX))
 
769
                        break; //
 
770
        } // FOR versions
 
771
 
 
772
        if ((notwins || it_done) && fl1 != 0xff) {
 
773
                fl1 &= (uchar) ~c_df_twins;
 
774
                fl2 &= (uchar) ~c_df_twins;
 
775
        }
 
776
 
 
777
        attr.difflg &= fl_retain;
 
778
 
 
779
        if (fl1 != 0xff) // some bases defined
 
780
        {
 
781
                attr.basflg = flt; // agree to 't' type
 
782
                if (fl1 & c_df_round)
 
783
                        attr.basflg |= CSTR_bs_round;
 
784
                if (cap_shape)
 
785
                        attr.basflg |= CSTR_bs_cap;
 
786
                if (fl2 & c_df_twins) // a non_cutten version had a twin
 
787
                {
 
788
                        if ((fl2t & (CSTR_db_b1 | CSTR_db_b2)) != (CSTR_db_b1 | CSTR_db_b2))
 
789
                        //  b1 or b2  were absent in full list
 
790
                        {
 
791
                                fl1 &= ~(CSTR_db_b1 | CSTR_db_b2); // forget b1/b2 as defined
 
792
                                if (attr.bas_acc & CSTR_ba_chance) // gleb
 
793
                                        attr.basflg |= (CSTR_bs_b1a | CSTR_bs_b2a); // agrees to be both b1. b2
 
794
                        }
 
795
                        if (disable_twins == 0 && fl1 & CSTR_db_b4)
 
796
                                fl1 &= ~CSTR_db_b4;
 
797
                }
 
798
                if (fl2 & (CSTR_db_b1 | c_df_b1a))
 
799
                        attr.basflg |= CSTR_bs_b1a;
 
800
                if (fl2 & (CSTR_db_b2 | c_df_b2a))
 
801
                        attr.basflg |= CSTR_bs_b2a;
 
802
                attr.difflg = attr.difflg | (fl1 & 15);
 
803
                if (flnt == 0)
 
804
                        attr.basflg |= CSTR_bs_t; // no "not a 't'" version
 
805
        }
 
806
 
 
807
        CSTR_SetAttr(B1, &attr);
882
808
}
883
809
 
884
810
///////////////
885
 
INT smart_diff(CSTR_rast c)
886
 
{
887
 
 INT d1,d2,bm,row;
888
 
 CSTR_rast_attr attr;
889
 
 
890
 
 CSTR_GetAttr(c,&attr);
891
 
 
892
 
 row = attr.row - minrow;
893
 
 d1 = row - bbs1;
894
 
 d2 = row - bbs2;
895
 
 bm = (bbs3 + bbs2)/2;
896
 
 
897
 
  #ifdef UFA // Valdemar 12-05-94 08:25pm
898
 
   return attr.bdiff;
899
 
  #endif
900
 
 
901
 
  if( attr.h >= Ps &&
902
 
          (abs(d1) < 2 || abs(d2) < 2) &&
903
 
          row+attr.h >= bbs3
904
 
        )
905
 
  {
906
 
   attr.bdiff=0; // don't touch letter
907
 
   attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
908
 
 
909
 
   CSTR_SetAttr(c, &attr);
910
 
  }  // �,�,�
911
 
 
912
 
  if(attr.h >= Ps + 2 ) // large letter
913
 
  {
914
 
   if(abs(d1) < 2 || abs(d2) < 2)
915
 
   {
916
 
    attr.bdiff=0; // don't touch letter
917
 
    attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
918
 
    attr.difflg |= CSTR_db_forbid;
919
 
   }
920
 
   else
921
 
   { // letter d'not lay on base
922
 
    if( row < (bbs1+bbs2)/2 )
923
 
                return 0;    // farewell !
924
 
    if( row < bbs2 )
925
 
        {
926
 
        if( row+attr.h < bbs3 )
927
 
                        return 0;   // farewell !
928
 
        else if( attr.bdiff > 0 )
929
 
               {
930
 
                attr.bdiff=0; // don't touch letter
931
 
                attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
932
 
               }
933
 
        }
934
 
   }
935
 
 
936
 
  }
937
 
 
938
 
  if( attr.h < Ps-1 && (attr.flg & (CSTR_f_let | CSTR_f_bad)) )
939
 
          // letter < Ps may be dust
940
 
  {
941
 
   if(abs(d1) < 2 || abs(d2) < 2)
942
 
   {
943
 
      attr.bdiff=0; // don't touch letter
944
 
      attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
945
 
      attr.difflg |= CSTR_db_forbid;
946
 
   }
947
 
  }
948
 
 
949
 
  CSTR_SetAttr(c, &attr);
950
 
 
951
 
return attr.bdiff ;
952
 
}
953
 
 
954
 
 
955
 
INT HIST_STATISTIC=0;
956
 
 
957
 
extern INT hist_b3[];
958
 
extern INT hist_b3_f[];
959
 
 
960
 
INT GetPsFromHeights(void)
961
 
{
962
 
  CSTR_rast c;
963
 
  CSTR_rast_attr attr;
964
 
  UniVersions vers;
965
 
 
966
 
  INT BPs,cDefs,i,max1,max2,ind1,ind2,peak2,h_size,b_top,n_sunk,b1_or_b2_rong;
967
 
  INT Hh[RASTER_MAX_HEIGHT*2]={0};
968
 
 
969
 
  HIST_STATISTIC=0;
970
 
 
971
 
  cDefs=BPs=peak2=n_sunk=0;
972
 
  h_size=RASTER_MAX_HEIGHT*2;
973
 
 
974
 
  if( Ns1 && Ns2 )
975
 
          b1_or_b2_rong = ( abs(bbs1-bbs2) > 3 ) ?   FALSE : TRUE;
976
 
  else
977
 
          b1_or_b2_rong=FALSE;
978
 
 
979
 
  c=cell_f();
980
 
//  while( (c=c->nextl)->nextl )
981
 
  while ( c=CSTR_GetNextRaster(c,f_letter) )
982
 
  {
983
 
    INT df,sn;
 
811
int16_t smart_diff(CSTR_rast c) {
 
812
        int16_t d1, d2, bm, row;
 
813
        CSTR_rast_attr attr;
984
814
 
985
815
        CSTR_GetAttr(c, &attr);
986
 
    df=attr.bdiff;
987
 
        if(df == 127 )
988
 
                df=0;
989
 
    b_top=attr.row-minrow;
990
 
    sn=(b_top+attr.h)-(df+bbs3);
991
 
    if(abs(sn) > ((attr.h+2)/5 - 2) )   // far from b3
992
 
    {
993
 
      if(sn > attr.h>>2)
994
 
                  n_sunk++;   // sunk letter
995
 
      continue;
996
 
    }
997
 
 
998
 
        CSTR_GetCollectionUni(c, &vers);
999
 
    if( vers.lnAltCnt>0 && BracketIn(&vers) )
1000
 
                continue; // bracket present in verses,
1001
 
                                                   // skip letter
1002
 
    Hh[attr.h]++;
1003
 
        cDefs++;   // accumulate to histogramm
1004
 
  }
1005
 
 
1006
 
   // find first peak
1007
 
   for(i=max1=ind1=0;i < h_size; i++)
1008
 
   {
1009
 
    if( max1 < Hh[i] )
1010
 
        {
1011
 
                max1 = Hh[i]; ind1 = i;
1012
 
        }
1013
 
   }
1014
 
 
1015
 
   max1*=2;
1016
 
   if( ind1 > 0 )
1017
 
           max1+=Hh[ind1-1]*2;
1018
 
   if( ind1 < h_size-1)
1019
 
           max1+=Hh[ind1+1]*2;
1020
 
   if( ind1 < h_size-2)
1021
 
           max1+=Hh[ind1+2];
1022
 
   if( ind1 >1 )
1023
 
           max1+=Hh[ind1-2];
1024
 
   max1/=2;
1025
 
 
1026
 
   if(max1)
1027
 
           ind1=flood_peak(Hh,ind1);
1028
 
 
1029
 
   if( cDefs>>1 > max1 )
1030
 
   {
1031
 
           multi_bas=4;
1032
 
           return 0;
1033
 
   }  // flooded
1034
 
 
1035
 
   // second peak
1036
 
   for(i=max2=ind2=0;i < h_size;i++)
1037
 
   {
1038
 
    if(i>=ind1-4 && i<=ind1+4) continue;
1039
 
    if( max2 < Hh[i] )
1040
 
        {
1041
 
                max2 = Hh[i]; ind2 = i;
1042
 
        }
1043
 
   }
1044
 
 
1045
 
   max2*=2;
1046
 
 
1047
 
   if( ind2 > 0 )
1048
 
           max2+=Hh[ind2-1]*2;
1049
 
 
1050
 
   if( ind2 < h_size-1)
1051
 
           max2+=Hh[ind2+1]*2;
1052
 
 
1053
 
   if( ind2 < h_size-2)
1054
 
           max2+=Hh[ind2+2];
1055
 
 
1056
 
   if( ind2 >1 )
1057
 
           max2+=Hh[ind2-2];
1058
 
 
1059
 
   max2/=2;
1060
 
 
1061
 
 
1062
 
   if(max2)
1063
 
           ind2=flood_peak(Hh,ind2);
1064
 
 
1065
 
 
1066
 
   if(max2 > 0 && ( abs(ind1-ind2) >= MIN(ind1,ind2)/3) )
1067
 
           peak2=1;
1068
 
 
1069
 
   if( max2 > 3 && peak2 )
1070
 
   {
1071
 
         BPs=MIN(ind1,ind2);
1072
 
     bbs1=bbs3-MAX(ind1,ind2);
1073
 
     goto ret;
1074
 
   } // two peaks
1075
 
 
1076
 
 
1077
 
   if( n_sunk > 2 && !b1_or_b2_rong )
1078
 
   {
1079
 
      INT TPs,ds;
1080
 
      TPs=def_upper_side();   // check tops
1081
 
      ds= ( peak2 && ind2 < ind1 ) ?  ind2 : ind1 ;
1082
 
      if( TPs > 0 && abs(TPs-ds) < 3 ) { BPs=ds; goto  ret; }
1083
 
   }
1084
 
 
1085
 
   if( b1_or_b2_rong == FALSE )
1086
 
   {
1087
 
    if(Ns2 > 0 && Ns2 >=Ns1)
1088
 
    {
1089
 
      INT BS2=bbs3-bbs2;
1090
 
      if( abs(ind1-BS2) < 3 )
1091
 
        { BPs=ind1; goto ret; }
1092
 
      else if( peak2 && abs(ind2-BS2) < 3 )
1093
 
        { BPs=ind2; goto ret; }
1094
 
    }
1095
 
    if(Ns1 > 0)
1096
 
    {
1097
 
      INT BS1=bbs3-bbs1;
1098
 
      if( abs(ind1-BS1) < 3 )
1099
 
        { BPs=-ind1; goto ret; }
1100
 
      else if( peak2 && abs(ind2-BS1) < 3 )
1101
 
        { BPs=-ind2; goto ret; }
1102
 
    }
1103
 
   } // if b1 or b2 not rong
1104
 
 
1105
 
   if( peak2 && ind1 < ind2 )
1106
 
   {
1107
 
           BPs=ind1;
1108
 
           goto ret;
1109
 
   }
1110
 
   if( !peak2 && n_sunk > 0 )
1111
 
   {
1112
 
           BPs=ind1;
1113
 
           goto ret;
1114
 
   }
1115
 
 
1116
 
   if((i=setup_let_case(ind1)))
1117
 
   {
1118
 
      if(i==1) BPs=-ind1;
1119
 
      if(i==2) BPs=ind1;
1120
 
      goto ret;
1121
 
   }
1122
 
 
1123
 
   if( peak2 && ind2 < ind1 )
1124
 
   {
1125
 
           BPs=-ind1;
1126
 
           goto ret;
1127
 
   }
1128
 
 
1129
 
    // default :
1130
 
    //           H > 30 : caps letters
1131
 
    //           else   : small
1132
 
   HIST_STATISTIC=2;
1133
 
   return ( ind1 > 30 ) ? (-ind1) : ind1 ;
1134
 
 
1135
 
   ret:
1136
 
    HIST_STATISTIC=1;
1137
 
    if(db_status & snap_activity_rbal(db_pass) )
1138
 
        {
1139
 
     CHAR buf[120];
1140
 
     sprintf(buf,"Histogramms: min=%d b3=%d peak1= %d|%d peak2= %d|%d sunk=%d",
1141
 
                              minrow,bbs3,    ind1,max1,   ind2,max2, n_sunk);
1142
 
     snap_show_text_rbal(buf); snap_monitor_rbal();
1143
 
    }
1144
 
    return BPs;
 
816
 
 
817
        row = attr.row - minrow;
 
818
        d1 = row - bbs1;
 
819
        d2 = row - bbs2;
 
820
        bm = (bbs3 + bbs2) / 2;
 
821
 
 
822
#ifdef UFA // Valdemar 12-05-94 08:25pm
 
823
        return attr.bdiff;
 
824
#endif
 
825
 
 
826
        if (attr.h >= Ps && (abs(d1) < 2 || abs(d2) < 2) && row + attr.h >= bbs3) {
 
827
                attr.bdiff = 0; // don't touch letter
 
828
                attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
 
829
 
 
830
                CSTR_SetAttr(c, &attr);
 
831
        } // �,�,�
 
832
 
 
833
        if (attr.h >= Ps + 2) // large letter
 
834
        {
 
835
                if (abs(d1) < 2 || abs(d2) < 2) {
 
836
                        attr.bdiff = 0; // don't touch letter
 
837
                        attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
 
838
                        attr.difflg |= CSTR_db_forbid;
 
839
                } else { // letter d'not lay on base
 
840
                        if (row < (bbs1 + bbs2) / 2)
 
841
                                return 0; // farewell !
 
842
                        if (row < bbs2) {
 
843
                                if (row + attr.h < bbs3)
 
844
                                        return 0; // farewell !
 
845
                                else if (attr.bdiff > 0) {
 
846
                                        attr.bdiff = 0; // don't touch letter
 
847
                                        attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
 
848
                                }
 
849
                        }
 
850
                }
 
851
 
 
852
        }
 
853
 
 
854
        if (attr.h < Ps - 1 && (attr.flg & (CSTR_f_let | CSTR_f_bad)))
 
855
        // letter < Ps may be dust
 
856
        {
 
857
                if (abs(d1) < 2 || abs(d2) < 2) {
 
858
                        attr.bdiff = 0; // don't touch letter
 
859
                        attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
 
860
                        attr.difflg |= CSTR_db_forbid;
 
861
                }
 
862
        }
 
863
 
 
864
        CSTR_SetAttr(c, &attr);
 
865
 
 
866
        return attr.bdiff;
 
867
}
 
868
 
 
869
int16_t HIST_STATISTIC = 0;
 
870
 
 
871
extern int16_t hist_b3[];
 
872
extern int16_t hist_b3_f[];
 
873
 
 
874
int16_t GetPsFromHeights(void) {
 
875
        CSTR_rast c;
 
876
        CSTR_rast_attr attr;
 
877
        UniVersions vers;
 
878
 
 
879
        int16_t BPs, cDefs, i, max1, max2, ind1, ind2, peak2, h_size, b_top, n_sunk,
 
880
                        b1_or_b2_rong;
 
881
        int16_t Hh[RASTER_MAX_HEIGHT * 2] = { 0 };
 
882
 
 
883
        HIST_STATISTIC = 0;
 
884
 
 
885
        cDefs = BPs = peak2 = n_sunk = 0;
 
886
        h_size = RASTER_MAX_HEIGHT * 2;
 
887
 
 
888
        if (Ns1 && Ns2)
 
889
                b1_or_b2_rong = (abs(bbs1 - bbs2) > 3) ? FALSE : TRUE;
 
890
        else
 
891
                b1_or_b2_rong = FALSE;
 
892
 
 
893
        c = cell_f();
 
894
        //  while( (c=c->nextl)->nextl )
 
895
        while (c = CSTR_GetNextRaster(c, f_letter)) {
 
896
                int16_t df, sn;
 
897
 
 
898
                CSTR_GetAttr(c, &attr);
 
899
                df = attr.bdiff;
 
900
                if (df == 127)
 
901
                        df = 0;
 
902
                b_top = attr.row - minrow;
 
903
                sn = (b_top + attr.h) - (df + bbs3);
 
904
                if (abs(sn) > ((attr.h + 2) / 5 - 2)) // far from b3
 
905
                {
 
906
                        if (sn > attr.h >> 2)
 
907
                                n_sunk++; // sunk letter
 
908
                        continue;
 
909
                }
 
910
 
 
911
                CSTR_GetCollectionUni(c, &vers);
 
912
                if (vers.lnAltCnt > 0 && BracketIn(&vers))
 
913
                        continue; // bracket present in verses,
 
914
                // skip letter
 
915
                Hh[attr.h]++;
 
916
                cDefs++; // accumulate to histogramm
 
917
        }
 
918
 
 
919
        // find first peak
 
920
        for (i = max1 = ind1 = 0; i < h_size; i++) {
 
921
                if (max1 < Hh[i]) {
 
922
                        max1 = Hh[i];
 
923
                        ind1 = i;
 
924
                }
 
925
        }
 
926
 
 
927
        max1 *= 2;
 
928
        if (ind1 > 0)
 
929
                max1 += Hh[ind1 - 1] * 2;
 
930
        if (ind1 < h_size - 1)
 
931
                max1 += Hh[ind1 + 1] * 2;
 
932
        if (ind1 < h_size - 2)
 
933
                max1 += Hh[ind1 + 2];
 
934
        if (ind1 > 1)
 
935
                max1 += Hh[ind1 - 2];
 
936
        max1 /= 2;
 
937
 
 
938
        if (max1)
 
939
                ind1 = flood_peak(Hh, ind1);
 
940
 
 
941
        if (cDefs >> 1 > max1) {
 
942
                multi_bas = 4;
 
943
                return 0;
 
944
        } // flooded
 
945
 
 
946
        // second peak
 
947
        for (i = max2 = ind2 = 0; i < h_size; i++) {
 
948
                if (i >= ind1 - 4 && i <= ind1 + 4)
 
949
                        continue;
 
950
                if (max2 < Hh[i]) {
 
951
                        max2 = Hh[i];
 
952
                        ind2 = i;
 
953
                }
 
954
        }
 
955
 
 
956
        max2 *= 2;
 
957
 
 
958
        if (ind2 > 0)
 
959
                max2 += Hh[ind2 - 1] * 2;
 
960
 
 
961
        if (ind2 < h_size - 1)
 
962
                max2 += Hh[ind2 + 1] * 2;
 
963
 
 
964
        if (ind2 < h_size - 2)
 
965
                max2 += Hh[ind2 + 2];
 
966
 
 
967
        if (ind2 > 1)
 
968
                max2 += Hh[ind2 - 2];
 
969
 
 
970
        max2 /= 2;
 
971
 
 
972
        if (max2)
 
973
                ind2 = flood_peak(Hh, ind2);
 
974
 
 
975
        if (max2 > 0 && (abs(ind1 - ind2) >= MIN(ind1, ind2) / 3))
 
976
                peak2 = 1;
 
977
 
 
978
        if (max2 > 3 && peak2) {
 
979
                BPs = MIN(ind1, ind2);
 
980
                bbs1 = bbs3 - MAX(ind1, ind2);
 
981
                goto ret;
 
982
        } // two peaks
 
983
 
 
984
 
 
985
        if (n_sunk > 2 && !b1_or_b2_rong) {
 
986
                int16_t TPs, ds;
 
987
                TPs = def_upper_side(); // check tops
 
988
                ds = (peak2 && ind2 < ind1) ? ind2 : ind1;
 
989
                if (TPs > 0 && abs(TPs - ds) < 3) {
 
990
                        BPs = ds;
 
991
                        goto ret;
 
992
                }
 
993
        }
 
994
 
 
995
        if (b1_or_b2_rong == FALSE) {
 
996
                if (Ns2 > 0 && Ns2 >= Ns1) {
 
997
                        int16_t BS2 = bbs3 - bbs2;
 
998
                        if (abs(ind1 - BS2) < 3) {
 
999
                                BPs = ind1;
 
1000
                                goto ret;
 
1001
                        } else if (peak2 && abs(ind2 - BS2) < 3) {
 
1002
                                BPs = ind2;
 
1003
                                goto ret;
 
1004
                        }
 
1005
                }
 
1006
                if (Ns1 > 0) {
 
1007
                        int16_t BS1 = bbs3 - bbs1;
 
1008
                        if (abs(ind1 - BS1) < 3) {
 
1009
                                BPs = -ind1;
 
1010
                                goto ret;
 
1011
                        } else if (peak2 && abs(ind2 - BS1) < 3) {
 
1012
                                BPs = -ind2;
 
1013
                                goto ret;
 
1014
                        }
 
1015
                }
 
1016
        } // if b1 or b2 not rong
 
1017
 
 
1018
        if (peak2 && ind1 < ind2) {
 
1019
                BPs = ind1;
 
1020
                goto ret;
 
1021
        }
 
1022
        if (!peak2 && n_sunk > 0) {
 
1023
                BPs = ind1;
 
1024
                goto ret;
 
1025
        }
 
1026
 
 
1027
        if ((i = setup_let_case(ind1))) {
 
1028
                if (i == 1)
 
1029
                        BPs = -ind1;
 
1030
                if (i == 2)
 
1031
                        BPs = ind1;
 
1032
                goto ret;
 
1033
        }
 
1034
 
 
1035
        if (peak2 && ind2 < ind1) {
 
1036
                BPs = -ind1;
 
1037
                goto ret;
 
1038
        }
 
1039
 
 
1040
        // default :
 
1041
        //           H > 30 : caps letters
 
1042
        //           else   : small
 
1043
        HIST_STATISTIC = 2;
 
1044
        return (ind1 > 30) ? (-ind1) : ind1;
 
1045
 
 
1046
        ret: HIST_STATISTIC = 1;
 
1047
        if (db_status & snap_activity_rbal(db_pass)) {
 
1048
                char buf[120];
 
1049
                sprintf(buf,
 
1050
                                "Histogramms: min=%d b3=%d peak1= %d|%d peak2= %d|%d sunk=%d",
 
1051
                                minrow, bbs3, ind1, max1, ind2, max2, n_sunk);
 
1052
                snap_show_text_rbal(buf);
 
1053
                snap_monitor_rbal();
 
1054
        }
 
1055
        return BPs;
1145
1056
}
1146
1057
 
1147
1058
////////////////
1148
1059
 
1149
 
static BYTE BracketsList[]="<>()[]";
1150
 
 
1151
 
BYTE BracketIn(UniVersions *v)
1152
 
{
1153
 
  int i;
1154
 
 
1155
 
  for(i=0 ; i<v->lnAltCnt; i++)
1156
 
  {
1157
 
   if( memchr(BracketsList,v->Alt[i].Liga,sizeof(BracketsList)-1) )
1158
 
           return 1;
1159
 
  }
1160
 
 
1161
 
  return 0;
 
1060
static uchar BracketsList[] = "<>()[]";
 
1061
 
 
1062
uchar BracketIn(UniVersions *v) {
 
1063
        int i;
 
1064
 
 
1065
        for (i = 0; i < v->lnAltCnt; i++) {
 
1066
                if (memchr(BracketsList, v->Alt[i].Liga, sizeof(BracketsList) - 1))
 
1067
                        return 1;
 
1068
        }
 
1069
 
 
1070
        return 0;
1162
1071
}
1163
1072
 
1164
1073
////////////
1165
1074
 
1166
 
INT def_upper_side(void)
1167
 
{
1168
 
  CSTR_rast c;
1169
 
  CSTR_rast_attr attr;
1170
 
  INT i,max,max_sn,ind,ind_sn;
1171
 
  WORD h_size,n_def,n_sn;
1172
 
 
1173
 
  INT h_top[RASTER_MAX_HEIGHT*2]={0},h_sunk[RASTER_MAX_HEIGHT*2]={0};
1174
 
 
1175
 
  h_size=RASTER_MAX_HEIGHT*2;
1176
 
 
1177
 
  c=cell_f();
1178
 
  n_def=n_sn=0;
1179
 
//  while( (c=c->nextl)->nextl )
1180
 
  while( (c=CSTR_GetNextRaster(c, CSTR_f_let)) )
1181
 
  {
1182
 
    INT df,sn,b_top;
1183
 
 
1184
 
//    if(!(c->flg & CSTR_f_let) ) continue;
1185
 
 
1186
 
        CSTR_GetAttr(c, &attr);
1187
 
 
1188
 
    df=attr.bdiff;
1189
 
        if(df == 127 )
1190
 
                df=0;             // + diff
1191
 
    b_top=attr.row-minrow;
1192
 
        sn=(b_top+attr.h)-(df+bbs3);
1193
 
 
1194
 
    if( b_top-df>=RASTER_MAX_HEIGHT*2 )
1195
 
        continue; // Oleg : for trash lines
1196
 
 
1197
 
    if(abs(sn) > ((attr.h+2)/5 - 2) )               // far from b3
1198
 
    {
1199
 
      if(sn > attr.h>>2)
1200
 
          {
1201
 
                  h_sunk[b_top-df]++;
1202
 
                  n_sn++;
1203
 
          }// sunk letter
1204
 
      continue;
1205
 
    }
1206
 
    h_top[b_top-df]++;
1207
 
        n_def++;
1208
 
  }
1209
 
 
1210
 
   //  find peak tops
1211
 
   for(i=max=ind=0;i < h_size; i++)
1212
 
   {
1213
 
    if( max < h_top[i] )
1214
 
     {
1215
 
      max = h_top[i];
1216
 
      ind=i;
1217
 
     }
1218
 
   }
1219
 
 
1220
 
   max*=2;
1221
 
   if( ind > 0 )
1222
 
       max+=h_top[ind-1]*2;
1223
 
   if( ind < h_size-1)
1224
 
       max+=h_top[ind+1]*2;
1225
 
   if( ind < h_size-2)
1226
 
       max+=h_top[ind+2];
1227
 
   if( ind >1 )
1228
 
       max+=h_top[ind-2];
1229
 
   max/=2;
1230
 
   if(max)
1231
 
       ind=flood_peak(h_top,ind);
1232
 
   if( n_def>>1 > max )
1233
 
       return FALSE;  // flooded tops
1234
 
 
1235
 
    // find peak tops of sunked
1236
 
   for(i=max_sn=ind_sn=0;i < h_size; i++)
1237
 
   {
1238
 
    if( max_sn < h_sunk[i] )
1239
 
        {
1240
 
                max_sn = h_sunk[i];
1241
 
                ind_sn=i;
1242
 
        }
1243
 
   }
1244
 
 
1245
 
   max_sn*=2;
1246
 
   if( ind_sn > 0 )       max_sn+=h_sunk[ind_sn-1]*2;
1247
 
   if( ind_sn < h_size-1) max_sn+=h_sunk[ind_sn+1]*2;
1248
 
   if( ind_sn < h_size-2) max_sn+=h_sunk[ind_sn+2];
1249
 
   if( ind_sn >1 )        max_sn+=h_sunk[ind_sn-2];
1250
 
   max_sn/=2;
1251
 
 
1252
 
   if(max_sn)
1253
 
           ind_sn=flood_peak(h_sunk,ind_sn);
1254
 
 
1255
 
   if( !max_sn || n_sn>>1 > max_sn )
1256
 
           return FALSE;  // flooded sunk tops
1257
 
 
1258
 
   return ( abs(ind-ind_sn)<=3 ) ?   bbs3-ind : FALSE ;
 
1075
int16_t def_upper_side(void) {
 
1076
        CSTR_rast c;
 
1077
        CSTR_rast_attr attr;
 
1078
        int16_t i, max, max_sn, ind, ind_sn;
 
1079
        uint16_t h_size, n_def, n_sn;
 
1080
 
 
1081
        int16_t h_top[RASTER_MAX_HEIGHT * 2] = { 0 }, h_sunk[RASTER_MAX_HEIGHT * 2] = {
 
1082
                        0 };
 
1083
 
 
1084
        h_size = RASTER_MAX_HEIGHT * 2;
 
1085
 
 
1086
        c = cell_f();
 
1087
        n_def = n_sn = 0;
 
1088
        //  while( (c=c->nextl)->nextl )
 
1089
        while ((c = CSTR_GetNextRaster(c, CSTR_f_let))) {
 
1090
                int16_t df, sn, b_top;
 
1091
 
 
1092
                //    if(!(c->flg & CSTR_f_let) ) continue;
 
1093
 
 
1094
                CSTR_GetAttr(c, &attr);
 
1095
 
 
1096
                df = attr.bdiff;
 
1097
                if (df == 127)
 
1098
                        df = 0; // + diff
 
1099
                b_top = attr.row - minrow;
 
1100
                sn = (b_top + attr.h) - (df + bbs3);
 
1101
 
 
1102
                if (b_top - df >= RASTER_MAX_HEIGHT * 2)
 
1103
                        continue; // Oleg : for trash lines
 
1104
 
 
1105
                if (abs(sn) > ((attr.h + 2) / 5 - 2)) // far from b3
 
1106
                {
 
1107
                        if (sn > attr.h >> 2) {
 
1108
                                h_sunk[b_top - df]++;
 
1109
                                n_sn++;
 
1110
                        }// sunk letter
 
1111
                        continue;
 
1112
                }
 
1113
                h_top[b_top - df]++;
 
1114
                n_def++;
 
1115
        }
 
1116
 
 
1117
        //  find peak tops
 
1118
        for (i = max = ind = 0; i < h_size; i++) {
 
1119
                if (max < h_top[i]) {
 
1120
                        max = h_top[i];
 
1121
                        ind = i;
 
1122
                }
 
1123
        }
 
1124
 
 
1125
        max *= 2;
 
1126
        if (ind > 0)
 
1127
                max += h_top[ind - 1] * 2;
 
1128
        if (ind < h_size - 1)
 
1129
                max += h_top[ind + 1] * 2;
 
1130
        if (ind < h_size - 2)
 
1131
                max += h_top[ind + 2];
 
1132
        if (ind > 1)
 
1133
                max += h_top[ind - 2];
 
1134
        max /= 2;
 
1135
        if (max)
 
1136
                ind = flood_peak(h_top, ind);
 
1137
        if (n_def >> 1 > max)
 
1138
                return FALSE; // flooded tops
 
1139
 
 
1140
        // find peak tops of sunked
 
1141
        for (i = max_sn = ind_sn = 0; i < h_size; i++) {
 
1142
                if (max_sn < h_sunk[i]) {
 
1143
                        max_sn = h_sunk[i];
 
1144
                        ind_sn = i;
 
1145
                }
 
1146
        }
 
1147
 
 
1148
        max_sn *= 2;
 
1149
        if (ind_sn > 0)
 
1150
                max_sn += h_sunk[ind_sn - 1] * 2;
 
1151
        if (ind_sn < h_size - 1)
 
1152
                max_sn += h_sunk[ind_sn + 1] * 2;
 
1153
        if (ind_sn < h_size - 2)
 
1154
                max_sn += h_sunk[ind_sn + 2];
 
1155
        if (ind_sn > 1)
 
1156
                max_sn += h_sunk[ind_sn - 2];
 
1157
        max_sn /= 2;
 
1158
 
 
1159
        if (max_sn)
 
1160
                ind_sn = flood_peak(h_sunk, ind_sn);
 
1161
 
 
1162
        if (!max_sn || n_sn >> 1 > max_sn)
 
1163
                return FALSE; // flooded sunk tops
 
1164
 
 
1165
        return (abs(ind - ind_sn) <= 3) ? bbs3 - ind : FALSE;
1259
1166
}
1260
1167
//////////////
1261
1168
 
1262
 
void tell_for_b3(INT hist_array[])
1263
 
{
1264
 
  INT i;
1265
 
  DWORD NDisp,ON3;
1266
 
 
1267
 
  stable_b3=FALSE;
1268
 
 
1269
 
  if( language != LANG_RUSSIAN )
1270
 
          return;
1271
 
  if( Ns3 < 5 )
1272
 
          return;
1273
 
 
1274
 
  NDisp=0;
1275
 
  bbs3=(sbs3+(Ns3>>1))/Ns3;
1276
 
 
1277
 
  for(i=0; i < RASTER_MAX_HEIGHT*2 ; i++)
1278
 
    NDisp+=hist_array[i]*((i-bbs3)*(i-bbs3));
1279
 
 
1280
 
  ON3 = (Ns3-1)*(Ns3-1);
1281
 
  if( 25*NDisp < ON3 ) stable_b3=TRUE;
1282
 
  return;
 
1169
void tell_for_b3(int16_t hist_array[]) {
 
1170
        int16_t i;
 
1171
        uint32_t NDisp, ON3;
 
1172
 
 
1173
        stable_b3 = FALSE;
 
1174
 
 
1175
        if (language != LANG_RUSSIAN)
 
1176
                return;
 
1177
        if (Ns3 < 5)
 
1178
                return;
 
1179
 
 
1180
        NDisp = 0;
 
1181
        bbs3 = (sbs3 + (Ns3 >> 1)) / Ns3;
 
1182
 
 
1183
        for (i = 0; i < RASTER_MAX_HEIGHT * 2; i++)
 
1184
                NDisp += hist_array[i] * ((i - bbs3) * (i - bbs3));
 
1185
 
 
1186
        ON3 = (Ns3 - 1) * (Ns3 - 1);
 
1187
        if (25* NDisp < ON3)
 
1188
                stable_b3 = TRUE;
 
1189
        return;
1283
1190
}
1284
1191
 
1285
1192
///////////////
1286
1193
 
1287
 
INT flood_peak(INT *Hh,INT ind)
1288
 
{
1289
 
 WORD Num,Den,t,t1;
1290
 
 
1291
 
 if(ind > 1)
1292
 
      t=Hh[ind-2]*(ind-2);
1293
 
 else t=0;
1294
 
 
1295
 
 if(ind > 0)
1296
 
      t1=Hh[ind-1]*(ind-1);
1297
 
 else t1=0;
1298
 
 
1299
 
 Num  = Hh[ind]*ind+t1+Hh[ind+1]*(ind+1)+
1300
 
        t+Hh[ind+2]*(ind+2);
1301
 
 if(ind > 1)
1302
 
      t=Hh[ind-2];
1303
 
 else t=0;
1304
 
 
1305
 
 if(ind > 0)
1306
 
      t1=Hh[ind-1];
1307
 
 else t1=0;
1308
 
 
1309
 
 Den  = Hh[ind]+t1+Hh[ind+1]+t+Hh[ind+2];
1310
 
 
1311
 
 return( (2*Num+Den)/2/Den );
 
1194
int16_t flood_peak(int16_t *Hh, int16_t ind) {
 
1195
        uint16_t Num, Den, t, t1;
 
1196
 
 
1197
        if (ind > 1)
 
1198
                t = Hh[ind - 2] * (ind - 2);
 
1199
        else
 
1200
                t = 0;
 
1201
 
 
1202
        if (ind > 0)
 
1203
                t1 = Hh[ind - 1] * (ind - 1);
 
1204
        else
 
1205
                t1 = 0;
 
1206
 
 
1207
        Num = Hh[ind] * ind + t1 + Hh[ind + 1] * (ind + 1) + t + Hh[ind + 2] * (ind
 
1208
                        + 2);
 
1209
        if (ind > 1)
 
1210
                t = Hh[ind - 2];
 
1211
        else
 
1212
                t = 0;
 
1213
 
 
1214
        if (ind > 0)
 
1215
                t1 = Hh[ind - 1];
 
1216
        else
 
1217
                t1 = 0;
 
1218
 
 
1219
        Den = Hh[ind] + t1 + Hh[ind + 1] + t + Hh[ind + 2];
 
1220
 
 
1221
        return ((2* Num + Den) / 2 / Den);
1312
1222
}
1313
1223
 
1314
1224
/////////
1315
 
INT is_cen_bottom_accent(BYTE c)
1316
 
{
1317
 
// ����������� ������� ������� 12.09.2000 E.P.
 
1225
int16_t is_cen_bottom_accent(uchar c) {
 
1226
        // ����������� ������� ������� 12.09.2000 E.P.
1318
1227
        return (
1319
1228
 
1320
 
        c== AA_bottom_accent            || c== a_bottom_accent          ||
1321
 
        c== CC_bottom_accent            || c== c_bottom_accent          ||
1322
 
        c== EE_bottom_accent            || c== e_bottom_accent          ||
1323
 
        c== SS_bottom_accent_latin      || c== s_bottom_accent_latin||
1324
 
        c== TT_bottom_accent            || c== t_bottom_accent          ||
 
1229
        c == AA_bottom_accent || c == a_bottom_accent || c == CC_bottom_accent || c
 
1230
                        == c_bottom_accent || c == EE_bottom_accent || c == e_bottom_accent
 
1231
                        || c == SS_bottom_accent_latin || c == s_bottom_accent_latin || c
 
1232
                        == TT_bottom_accent || c == t_bottom_accent ||
1325
1233
 
1326
1234
        0);
1327
1235
}