2
Copyright (c) 1993-2008, Cognitive Technologies
5
����������� ��������� ��������������� � ������������� ��� � ���� ��������� ����,
6
��� � � �������� �����, � ����������� ��� ���, ��� ���������� ��������� �������:
8
* ��� ��������� ��������������� ��������� ���� ������ ���������� ���������
9
���� ����������� �� ��������� �����, ���� ������ ������� � �����������
11
* ��� ��������� ��������������� ��������� ���� � ������������ �/��� �
12
������ ����������, ������������ ��� ���������������, ������ �����������
13
��������� ���� ���������� �� ��������� �����, ���� ������ ������� �
14
����������� ����� �� ��������.
15
* �� �������� Cognitive Technologies, �� ����� �� ����������� �� �����
16
���� ������������ � �������� �������� ��������� �/��� �����������
17
���������, ���������� �� ���� ��, ��� ���������������� �����������
20
��� ��������� ������������� ����������� ��������� ���� �/��� ������� ������ "���
21
��� ����" ��� ������-���� ���� ��������, ���������� ���� ��� ���������������,
22
������� �������� ������������ �������� � ����������� ��� ���������� ����, �� ��
23
������������� ���. �� �������� ��������� ���� � �� ���� ������ ����, �������
24
����� �������� �/��� �������� �������������� ���������, �� � ���� ������ ��
25
��Ѩ� ���������������, ������� ����� �����, ���������, ����������� ���
26
������������� ������, ��������� � �������������� ��� ���������� ����������
27
������������� ������������� ��������� (������� ������ ������, ��� ������,
28
������� ���������, ��� ������ �/��� ������ �������, ���������� ��-�� ��������
29
������� ��� �/��� ������ ��������� �������� ��������� � ������� �����������,
30
�� �� ������������� ����� ��������), �� �� ������������� ���, ���� ���� �����
31
�������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
33
Redistribution and use in source and binary forms, with or without modification,
34
are permitted provided that the following conditions are met:
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.
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.
2
Copyright (c) 1993-2008, Cognitive Technologies
5
����������� ��������� ��������������� � ������������� ��� � ���� ��������� ����,
6
��� � � �������� �����, � ����������� ��� ���, ��� ���������� ��������� �������:
8
* ��� ��������� ��������������� ��������� ���� ������ ���������� ���������
9
���� ����������� �� ��������� �����, ���� ������ ������� � �����������
11
* ��� ��������� ��������������� ��������� ���� � ������������ �/��� �
12
������ ����������, ������������ ��� ���������������, ������ �����������
13
��������� ���� ���������� �� ��������� �����, ���� ������ ������� �
14
����������� ����� �� ��������.
15
* �� �������� Cognitive Technologies, �� ����� �� ����������� �� �����
16
���� ������������ � �������� �������� ��������� �/��� �����������
17
���������, ���������� �� ���� ��, ��� ���������������� �����������
20
��� ��������� ������������� ����������� ��������� ���� �/��� ������� ������ "���
21
��� ����" ��� ������-���� ���� ��������, ���������� ���� ��� ���������������,
22
������� �������� ������������ �������� � ����������� ��� ���������� ����, �� ��
23
������������� ���. �� �������� ��������� ���� � �� ���� ������ ����, �������
24
����� �������� �/��� �������� �������������� ���������, �� � ���� ������ ��
25
��Ѩ� ���������������, ������� ����� �����, ���������, ����������� ���
26
������������� ������, ��������� � �������������� ��� ���������� ����������
27
������������� ������������� ��������� (������� ������ ������, ��� ������,
28
������� ���������, ��� ������ �/��� ������ �������, ���������� ��-�� ��������
29
������� ��� �/��� ������ ��������� �������� ��������� � ������� �����������,
30
�� �� ������������� ����� ��������), �� �� ������������� ���, ���� ���� �����
31
�������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
33
Redistribution and use in source and binary forms, with or without modification,
34
are permitted provided that the following conditions are met:
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.
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.
57
57
#include <stdlib.h>
59
59
#include <string.h>
67
64
#include "linear.h"
69
65
#include "linutil.h"
70
66
#include "ligas.h" // Pit 10-10-94 03:56pm
71
67
#include "minmax.h"
73
69
/*============= Func prototypes ==================*/
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);
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);
85
81
#define MAX_HEIGHT 70 // such was... change ?
87
extern Word8 language;
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;
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
94
89
/*============= Local function portotypes ==============*/
96
/*static*/ INT h_hist(void);
91
/*static*/int16_t h_hist(void);
98
93
/*============= Source code ============*/
99
BOOL is_liga_ff(BYTE c)
101
// ��� ���� ��������� ����� ����� � ligas.h 05.09.2000 E.P.
104
BOOL is_liga_ffl(BYTE c)
106
// ��� ���� ��������� ����� ����� � ligas.h 05.09.2000 E.P.
107
return (c==liga_ffl);
111
INT is_russian(BYTE ch)
113
if( language==LANG_RUSSIAN || language==LANG_ENGLISH && multy_language )
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)
122
case ED_WIN: // for Windows (ANSI)
123
if( (ch >=0xE0 && ch <=0xFF)||(ch >=(BYTE)'�' && ch <=(BYTE)'�'))
126
case ED_MAC: // for Macintosh
128
(ch >=0xE0 && ch <=0xFE) || ch == 0xDF || (ch >= 0xC0 && ch <= 0xDF)
136
INT is_english(BYTE ch)
138
return (ch >= 'a' && ch <= 'z')||(ch >= 'A' && ch <= 'Z')||
140
// ch>=ligas_beg && ch<=ligas_end &&
141
is_liga(ch) && // 14.09.2000 E.P.
143
ch!=liga_exm && ch!=liga_qm )
147
INT is_serbian_special(BYTE ch)
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 );
158
INT is_polish_special(BYTE ch)
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
172
INT is_czech_special(BYTE let)
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
193
INT is_roman_special(BYTE let)
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
204
INT is_hungar_special(BYTE let)
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
216
INT is_lower(BYTE ch)
219
if(language==LANG_RUSSIAN)
221
case ED_ASCII: // for ASCII
222
if((ch >=(BYTE)'�' && ch <=(BYTE)'�') ||
223
(ch >=(BYTE)'�' && ch <=(BYTE)'�') ||
224
memchr("�������",ch,7)
227
case ED_WIN: // for Windows (ANSI)
228
if (ch >=0xE0 && ch <=0xFF)
231
case ED_MAC: // for Macintosh
232
if(((ch >=0xE0 && ch <=0xFE) || ch == 0xDF)
236
if(ch >= 'a' && ch <= 'z') return 1;
239
INT is_upper(BYTE ch)
241
if(language==LANG_RUSSIAN)
244
case ED_MAC: // for ASCII and Macintosh
245
if(ch >=(BYTE)'�' && ch <=(BYTE)'�'||
249
case ED_WIN: // for Windows (ANSI)
250
if(ch >= 0xC0 && ch <= 0xDF)
254
if(ch >= 'A' && ch <= 'Z') return 1;
258
BOOL is_digit(BYTE ch)
260
if(ch >= (BYTE)'0' && ch <= (BYTE)'9') return TRUE;
264
INT isletter(BYTE ch)
266
if(is_lower(ch) || is_upper(ch)) return 1;
270
BYTE get_homot(BYTE ch )
272
if(ch == '0') return ((BYTE)'�');
273
if(is_upper(ch)) return to_lower(ch);
274
if(is_lower(ch)) return to_upper(ch);
278
static const BYTE non_twin[]="������";
279
static const BYTE lat_twins[]="cCoOpPsSvVwWxXzZ";
283
if(!isletter(ch)) return 0;
284
if( language==LANG_RUSSIAN )
285
if(memchr(non_twin,ch,sizeof non_twin)) return 0;
287
if( language!=LANG_RUSSIAN && memchr(lat_twins,ch,sizeof lat_twins)) return 1;
94
Bool is_liga_ff(uchar c) {
95
// ��� ���� ��������� ����� ����� � ligas.h 05.09.2000 E.P.
96
return (c == liga_ff);
98
Bool is_liga_ffl(uchar c) {
99
// ��� ���� ��������� ����� ����� � ligas.h 05.09.2000 E.P.
100
return (c == liga_ffl);
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.
108
ch != liga_exm && ch != liga_qm);
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);
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
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);
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
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);
159
int16_t is_lower(uchar ch) {
161
if (language == LANG_RUSSIAN)
163
case ED_ASCII: // for ASCII
164
if ((ch >= (uchar) '�' && ch <= (uchar) '�') || (ch >= (uchar) '�'
165
&& ch <= (uchar) '�') || memchr("�������", ch, 7))
168
case ED_WIN: // for Windows (ANSI)
169
if (ch >= 0xE0 && ch <= 0xFF)
172
case ED_MAC: // for Macintosh
173
if (((ch >= 0xE0 && ch <= 0xFE) || ch == 0xDF))
177
if (ch >= 'a' && ch <= 'z')
181
int16_t is_upper(uchar ch) {
182
if (language == LANG_RUSSIAN)
185
case ED_MAC: // for ASCII and Macintosh
186
if (ch >= (uchar) '�' && ch <= (uchar) '�' || ch
187
== (uchar) r_EE_2dot)
190
case ED_WIN: // for Windows (ANSI)
191
if (ch >= 0xC0 && ch <= 0xDF)
195
if (ch >= 'A' && ch <= 'Z')
200
Bool is_digit(uchar ch) {
201
if (ch >= (uchar) '0' && ch <= (uchar) '9')
207
int16_t isletter(uchar ch) {
208
if (is_lower(ch) || is_upper(ch))
214
uchar get_homot(uchar ch) {
216
return ((uchar) '�');
224
static const uchar non_twin[] = "������";
225
static const uchar lat_twins[] = "cCoOpPsSvVwWxXzZ";
227
int16_t twin(uchar ch) {
230
if (language == LANG_RUSSIAN)
231
if (memchr(non_twin, ch, sizeof non_twin))
235
if (language != LANG_RUSSIAN && memchr(lat_twins, ch, sizeof lat_twins))
291
240
/* Function returns UPPER CASE variant of the letter. */
292
BYTE to_upper( BYTE c )
294
if ( c >= (BYTE)'a' && c <= (BYTE)'z') return c - (BYTE)'a' + (BYTE)'A';
295
if(language==LANG_RUSSIAN)
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)'�';
301
case ED_WIN: // for Windows (ANSI)
302
if ( c >= 0xE0 && c <= 0xFF ) return c - 0xE0 + 0xC0;
304
case ED_MAC: // for Macintosh
305
if ((c >= 0xE0 && c <= 0xFE) ) return c - 0xE0 + 0x80;
306
if ( c == 0xDF ) return 0x9F;
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)
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) '�';
252
case ED_WIN: // for Windows (ANSI)
253
if (c >= 0xE0 && c <= 0xFF)
254
return c - 0xE0 + 0xC0;
256
case ED_MAC: // for Macintosh
257
if ((c >= 0xE0 && c <= 0xFE))
258
return c - 0xE0 + 0x80;
312
/* Function returns LOWER CASE variant of the letter. */
313
BYTE to_lower(BYTE c)
315
if ( c >= (BYTE)'A' && c <= (BYTE)'Z') return c - (BYTE)'A'+ (BYTE)'a' ;
316
if(language==LANG_RUSSIAN)
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)'�' ;
322
case ED_WIN: // for Windows
323
if ( c >= 0xC0 && c <= 0xDF) return c - 0xC0 + 0xE0 ;
325
case ED_MAC: // for Macintosh
326
if ( c >= 0x80 && c <= 0x9E) return c - 0x80 + 0xE0 ;
327
if ( c == 0x9F ) return 0xDF;
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)
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) '�';
278
case ED_WIN: // for Windows
279
if (c >= 0xC0 && c <= 0xDF)
280
return c - 0xC0 + 0xE0;
282
case ED_MAC: // for Macintosh
283
if (c >= 0x80 && c <= 0x9E)
284
return c - 0x80 + 0xE0;
343
302
// ����� ������������� ��� ���� �����, �.�. � count_line_hi()
344
303
// �� ��� ���� ����� ����� ��������! � ����� ���������� � ���� �������
345
304
// ��������� �� �������� ����� (��� ����� ������ �����������)
346
void BaseLineStatisticInit(void)
305
void BaseLineStatisticInit(void) {
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
353
311
/////////////////
354
INT count_line_hi(void)
356
INT d23[MAX_HEIGHT]={0},
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;
365
if(line_number >= arrnum(lht))
320
if (line_number >= arrnum(lht))
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 ?
324
if (!(ncletrs > 6 && ncletrs * 2 > ncbs)) // Presentable line ?
373
328
//while((c=c->nextl)->nextl != NULL)
374
while((c=CSTR_GetNextRaster(c,CSTR_f_let)) != NULL)
376
CSTR_GetAttr(c,&attr);
378
if(attr.h <0 || attr.h >= MAX_HEIGHT )
381
CSTR_GetCollectionUni(c,&vers);
383
if(vers.lnAltCnt<=0 || vers.Alt[0].Prob < 140)
386
ch = let_lindef[vers.Alt[0].Liga];
387
if((ch & (v_bs1 | v_bs3)) == (v_bs1 | v_bs3))
392
if((ch & (v_bs2 | v_bs3)) == (v_bs2 | v_bs3))
329
while ((c = CSTR_GetNextRaster(c, CSTR_f_let)) != NULL) {
330
CSTR_GetAttr(c, &attr);
332
if (attr.h < 0 || attr.h >= MAX_HEIGHT)
335
CSTR_GetCollectionUni(c, &vers);
337
if (vers.lnAltCnt <= 0 || vers.Alt[0].Prob < 140)
340
ch = let_lindef[vers.Alt[0].Liga];
341
if ((ch & (v_bs1 | v_bs3)) == (v_bs1 | v_bs3)) {
345
if ((ch & (v_bs2 | v_bs3)) == (v_bs2 | v_bs3)) {
399
351
// test - what we got
400
for(i=0,max=0,index=0;i < sizeof(d13)/sizeof(d13[0]);i++)
404
max = d13[i]; index = i;
409
lht[line_number].caps = (BYTE)index;
411
for(i=0,max=0,index=0;i < sizeof(d23)/sizeof(d23[0]);i++)
415
max = d23[i]; index = i;
419
if( max > 0 ) lht[line_number].lcase = (BYTE)index;
421
lht[line_number].ns1 = nbcaps;
422
lht[line_number].ns2 = nbsmall;
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++) {
360
lht[line_number].caps = (uchar) index;
362
for (i = 0, max = 0, index = 0; i < sizeof(d23) / sizeof(d23[0]); i++) {
370
lht[line_number].lcase = (uchar) index;
372
lht[line_number].ns1 = nbcaps;
373
lht[line_number].ns2 = nbsmall;
375
return (lht[line_number].caps != 0 || lht[line_number].lcase != 0); /* if there some information */
428
378
/* Return most usable height in line */
433
INT h[MAX_HEIGHT]={0},th[MAX_HEIGHT]={0},
435
recognized=0,total=0;
440
// while((c=c->nextl)->nextl != NULL)
441
while((c=CSTR_GetNextRaster(c,f_letter)) != NULL)
443
CSTR_GetAttr(c,&attr);
444
if(attr.h <0 || attr.h >= MAX_HEIGHT )
448
th[attr.h]++; // all over
450
CSTR_GetCollectionUni(c,&vers);
452
// if(!(c->flg & CSTR_f_let))continue;
453
if( !(attr.flg & CSTR_f_let ) || vers.lnAltCnt<=0 )
456
ch = let_lindef[vers.Alt[0].Liga];
457
if((ch & v_bs3) && ((ch & v_bs1) || (ch & v_bs2)))
464
if(recognized > 3 || recognized*2 > total)
466
for(i=0,max=0,index=0;i < sizeof(h)/sizeof(h[0]);i++)
470
max = h[i]; index = i;
482
{ // letters have the same height
483
if( max*4 >= recognized*3 ) return index;
488
else if(recognized < 4 && total > 4 )
490
for(i=0,max=0,index=0;i < sizeof(th)/sizeof(th[0]);i++)
494
max = th[i]; index = i;
504
if(max*2 > total ) return index; // letters have the same height
507
for(i=0,max=0,index=0;i < sizeof(th)/sizeof(th[0]);i++)
511
max = th[i]; index = i;
515
if(max+th[index+1]+th[index-1] == total )
379
int16_t h_hist(void) {
382
int16_t h[MAX_HEIGHT] = { 0 }, th[MAX_HEIGHT] = { 0 }, i, max, index,
383
recognized = 0, total = 0;
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)
395
th[attr.h]++; // all over
397
CSTR_GetCollectionUni(c, &vers);
399
// if(!(c->flg & CSTR_f_let))continue;
400
if (!(attr.flg & CSTR_f_let) || vers.lnAltCnt <= 0)
403
ch = let_lindef[vers.Alt[0].Liga];
404
if ((ch & v_bs3) && ((ch & v_bs1) || (ch & v_bs2))) {
410
if (recognized > 3 || recognized * 2 > total) {
411
for (i = 0, max = 0, index = 0; i < sizeof(h) / sizeof(h[0]); i++) {
419
max += h[index - 1] * 2;
420
max += h[index + 1] * 2;
425
if (recognized > 4) { // letters have the same height
426
if (max * 4 >= recognized * 3)
432
else if (recognized < 4 && total > 4) {
433
for (i = 0, max = 0, index = 0; i < sizeof(th) / sizeof(th[0]); i++) {
441
max += th[index - 1] * 2;
442
max += th[index + 1] * 2;
443
max += th[index + 2];
444
max += th[index - 2];
447
return index; // letters have the same height
450
for (i = 0, max = 0, index = 0; i < sizeof(th) / sizeof(th[0]); i++) {
457
if (max + th[index + 1] + th[index - 1] == total)
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;
527
INT setup_let_case(INT ckH)
529
INT i,umax,lmax,lh,uprob,lprob,ret=0;
530
INT uc[MAX_HEIGHT]={0},
533
// Nick 26.01.2000 - � �������� ����� ���� ����� ������� ������ �����!
534
int lastLineNumber = MIN(sizeof(lht)/sizeof(lht[0]), line_number );
535
int firLineNumber = 1; // � ��� ��� ����� 0
538
//if(line_number < 2) return 0;
541
if((lh = h_hist()) == 0) return 0;
543
for(i=firLineNumber;i < line_number && i < sizeof(lht)/sizeof(lht[0]);i++)
545
uc[MIN(lht[i].caps,MAX_HEIGHT-1)]++; /* Calc histogram */
546
lc[MIN(lht[i].lcase,MAX_HEIGHT-1)]++; // Nick 25.05.2001
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];
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
556
if( abs(lht[i].caps-lh) < 3 )
560
if(lmax >= umax && lmax > 0)
562
ret=2; if(!ckH) page_stat=1;
564
if(umax > lmax && umax > 0)
566
ret=1; if(!ckH) page_stat=1;
568
if(db_status & snap_activity_rbal(db_pass) && ret!=0)
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();
467
uchar page_stat, stable_b3;
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 };
473
// Nick 26.01.2000 - � �������� ����� ���� ����� ������� ������ �����!
474
int lastLineNumber = MIN(sizeof(lht) / sizeof(lht[0]), line_number);
475
int firLineNumber = 1; // � ��� ��� ����� 0
478
//if(line_number < 2) return 0;
481
else if ((lh = h_hist()) == 0)
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
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];
492
for (i = firLineNumber, lprob = 0; i < lastLineNumber; i++) // Nick 26.01.2001 - was line_number
493
if (abs(lht[i].lcase - lh) < 3)
495
for (i = firLineNumber, uprob = 0; i < lastLineNumber; i++) // Nick 26.01.2001 - was line_number
497
if (abs(lht[i].caps - lh) < 3)
501
if (lmax >= umax && lmax > 0) {
506
if (umax > lmax && umax > 0) {
511
if (db_status & snap_activity_rbal(db_pass) && ret != 0) {
513
sprintf(buf, "Page statistic lh=%u caps=%u,%u lcase=%u,%u ", lh, umax,
515
snap_show_text_rbal(buf);
578
521
/********************************************************
580
523
* Func walk by string tries to discrim some *
582
525
* Only for russian language. *
583
526
********************************************************/
585
INT draft_cut_hyps(INT bs,INT flag)
592
BYTE ldef,let,gtwin=0;
593
INT dist,cutting_made=0,diff;
597
if( flag ) // add homotetia versions
599
// while ((c=c->nextl)->nextl)
600
while ((c=CSTR_GetNextRaster(c,CSTR_f_let)) )
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) )
610
let = is_lower(let) ? to_upper(let) : to_lower(let);
611
promote(0,c,let,0); // insvers
613
// c->vers[c->nvers].let=c->vers[c->nvers].prob=0;
618
if(bs == 3) // cut hyps by bb3
620
while ((c=CSTR_GetNextRaster(c,CSTR_f_let)))
622
// if(!(c->flg & CSTR_f_let)) continue;
623
CSTR_GetAttr(c,&attr);
626
if( attr.bdiff!=127 )
629
CSTR_GetCollectionUni(c,&vers);
631
// for (v=c->vers; (let=v->let) != 0; v++)
632
for(i=0;i<vers.lnAltCnt;i++)
634
dist = abs((attr.row + attr.h) - ( minrow + bbs3 + diff )); // Is it far from bbs3
635
let = vers.Alt[i].Liga;
637
ldef = let_linpos[let] & 0x0f;
638
if(memchr("���",let,3))
639
continue; // don't discrim
640
if(memchr("����",let,4))
643
if(ldef == 2) // Is it sunk letter
646
{ // Yes try to discrim
647
//v->prob |= 1; // Exclude from statistic by base line detection
648
vers.Alt[i].Prob |= 1;
652
if(ldef & 1 && ldef != 7) // Is it lay on bs3 don't touch �,�,�
655
{ // Yes try to discrim
657
vers.Alt[i].Prob |= 1;
664
CSTR_StoreCollectionUni(c,&vers);
672
// while ((c=c->nextl)->nextl)
673
while ((c=CSTR_GetNextRaster(c,CSTR_f_let)))
675
// if(!(c->flg & CSTR_f_let)) continue;
676
CSTR_GetAttr(c,&attr);
677
CSTR_GetCollectionUni(c,&vers);
679
// for (v=c->vers; (let=v->let) != 0; v++)
680
for(i=0;i<vers.lnAltCnt;i++)
682
let = vers.Alt[i].Liga;
684
ldef = let_linpos[let] >> 4;
685
dist = (bbs3-Ps) - (attr.row-minrow);
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
694
if( ldef & 1 && dist <= 3 ) // capital
697
vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
703
CSTR_StoreCollectionUni(c,&vers);
710
while ((c=CSTR_GetNextRaster(c,CSTR_f_let)))
712
// if(!(c->flg & CSTR_f_let)) continue;
713
CSTR_GetAttr(c,&attr);
714
CSTR_GetCollectionUni(c,&vers);
716
// for (v=c->vers; (let=v->let) != 0; v++)
717
for(i=0;i<vers.lnAltCnt;i++)
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
724
//v->prob |= 1; // Exclude from statistic by base line detection
725
vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
728
if( (ldef & 2)==2 && dist<=3 ) // small
731
vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
737
CSTR_StoreCollectionUni(c,&vers);
742
return (cutting_made || gtwin);
528
int16_t draft_cut_hyps(int16_t bs, int16_t flag) {
534
uchar ldef, let, gtwin = 0;
535
int16_t dist, cutting_made = 0, diff;
539
if (flag) // add homotetia versions
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))
551
let = is_lower(let) ? to_upper(let) : to_lower(let);
552
promote(0, c, let, 0); // insvers
554
// c->vers[c->nvers].let=c->vers[c->nvers].prob=0;
559
if (bs == 3) // cut hyps by bb3
561
while ((c = CSTR_GetNextRaster(c, CSTR_f_let))) {
562
// if(!(c->flg & CSTR_f_let)) continue;
563
CSTR_GetAttr(c, &attr);
566
if (attr.bdiff != 127)
569
CSTR_GetCollectionUni(c, &vers);
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;
576
ldef = let_linpos[let] & 0x0f;
577
if (memchr("���", let, 3))
578
continue; // don't discrim
579
if (memchr("����", let, 4))
582
if (ldef == 2) // Is it sunk letter
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;
590
if (ldef & 1 && ldef != 7) // Is it lay on bs3 don't touch �,�,�
592
if (dist > 2) { // Yes try to discrim
594
vers.Alt[i].Prob |= 1;
601
CSTR_StoreCollectionUni(c, &vers);
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);
614
// for (v=c->vers; (let=v->let) != 0; v++)
615
for (i = 0; i < vers.lnAltCnt; i++) {
616
let = vers.Alt[i].Liga;
618
ldef = let_linpos[let] >> 4;
619
dist = (bbs3 - Ps) - (attr.row - minrow);
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
627
if (ldef & 1 && dist <= 3) // capital
630
vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
636
CSTR_StoreCollectionUni(c, &vers);
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);
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
654
//v->prob |= 1; // Exclude from statistic by base line detection
655
vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
658
if ((ldef & 2) == 2 && dist <= 3) // small
661
vers.Alt[i].Prob |= 1; // Exclude from statistic by base line detection
667
CSTR_StoreCollectionUni(c, &vers);
672
return (cutting_made || gtwin);
745
extern BYTE disable_twins;
748
void set_rus_difflg(CSTR_rast B1, INT filter)
755
BYTE fl1, fl2, fl2t, flt, flnt, fl_cut, fl_retain;
759
BYTE cap_shape,solid,notwins;
761
fl_cut = filter & f_cut;
762
fl_retain = filter & f_retain;
763
fl1=0xff; // all lines defined
766
notwins=disable_twins == 1 ? 1 : 0;
768
flnt = 0; // 't' only
771
env = CSTR_GetComp(B1);
773
cap_shape = 1; // capital in shape
775
CSTR_GetAttr(B1,&attr);
776
CSTR_GetCollectionUni(B1,&vers);
778
// for (v0=B1->vers; (let=v0->let) != 0; v0++)
779
for(i=0;i<vers.lnAltCnt;i++)
783
v0->prob &= 0xfe; continue; // clear cut flag
786
let = vers.Alt[i].Liga;
788
tbe = let_lindef[let];
789
tshp = let_linshape[let];
793
solid += tbe < 32; // is it letter without twins
796
if (env->large & CCOM_LR_UNDERLINED)
798
if (tshp & 2) // sticky in shape
799
{ fl1=0; break; } // no lines defined
802
fl2t |= tbe; // accumulate b1/b2
804
//if (v0->prob & 1) // cutten version
805
if (vers.Alt[i].Prob & 1) // cutten version
808
if( disable_twins == 2)
810
if( memchr("����",let,4))
814
fl2 |= tbe; // accumulate b1/b2
816
if (tshp & 4) // stick allows to define bs1 ( iI1l )
818
if (oNb2 > 3) // base 2 defined
820
if (attr.h > (oPs + 3))
821
{ tbe |= 1; } // allow to def bs1
826
// retain only b3 line for sticks while dusts not present
828
fl1=0xff; break; // stick can't define any bases
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 &&
840
( attr.recsource & CSTR_rs_BOX )
845
if((notwins || it_done) && fl1 != 0xff )
847
fl1 &=(BYTE)~c_df_twins;
848
fl2 &=(BYTE)~c_df_twins;
851
attr.difflg &= fl_retain;
853
if (fl1 != 0xff) // some bases defined
855
attr.basflg = flt; // agree to 't' type
856
if (fl1 & c_df_round)
857
attr.basflg |= CSTR_bs_round;
859
attr.basflg |= CSTR_bs_cap;
860
if (fl2 & c_df_twins) // a non_cutten version had a twin
862
if ((fl2t & (CSTR_db_b1 | CSTR_db_b2)) != (CSTR_db_b1 | CSTR_db_b2))
863
// b1 or b2 were absent in full list
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
869
if( disable_twins == 0 && fl1 & CSTR_db_b4)
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);
878
attr.basflg |= CSTR_bs_t; // no "not a 't'" version
881
CSTR_SetAttr(B1,&attr);
675
extern uchar disable_twins;
676
extern int16_t it_done;
678
void set_rus_difflg(CSTR_rast B1, int16_t filter) {
683
uchar let, tbe, tshp;
684
uchar fl1, fl2, fl2t, flt, flnt, fl_cut, fl_retain;
688
uchar cap_shape, solid, notwins;
690
fl_cut = filter & f_cut;
691
fl_retain = filter & f_retain;
692
fl1 = 0xff; // all lines defined
695
notwins = disable_twins == 1 ? 1 : 0;
697
flnt = 0; // 't' only
700
env = CSTR_GetComp(B1);
702
cap_shape = 1; // capital in shape
704
CSTR_GetAttr(B1, &attr);
705
CSTR_GetCollectionUni(B1, &vers);
707
// for (v0=B1->vers; (let=v0->let) != 0; v0++)
708
for (i = 0; i < vers.lnAltCnt; i++) {
711
v0->prob &= 0xfe; continue; // clear cut flag
714
let = vers.Alt[i].Liga;
716
tbe = let_lindef[let];
717
tshp = let_linshape[let];
721
solid += tbe < 32; // is it letter without twins
724
if (env->large & CCOM_LR_UNDERLINED) {
725
if (tshp & 2) // sticky in shape
729
} // no lines defined
732
fl2t |= tbe; // accumulate b1/b2
734
//if (v0->prob & 1) // cutten version
735
if (vers.Alt[i].Prob & 1) // cutten version
738
if (disable_twins == 2) {
739
if (memchr("����", let, 4))
743
fl2 |= tbe; // accumulate b1/b2
745
if (tshp & 4) // stick allows to define bs1 ( iI1l )
747
if (oNb2 > 3) // base 2 defined
749
if (attr.h > (oPs + 3)) {
751
} // allow to def bs1
755
// retain only b3 line for sticks while dusts not present
757
fl1=0xff; break; // stick can't define any bases
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))
772
if ((notwins || it_done) && fl1 != 0xff) {
773
fl1 &= (uchar) ~c_df_twins;
774
fl2 &= (uchar) ~c_df_twins;
777
attr.difflg &= fl_retain;
779
if (fl1 != 0xff) // some bases defined
781
attr.basflg = flt; // agree to 't' type
782
if (fl1 & c_df_round)
783
attr.basflg |= CSTR_bs_round;
785
attr.basflg |= CSTR_bs_cap;
786
if (fl2 & c_df_twins) // a non_cutten version had a twin
788
if ((fl2t & (CSTR_db_b1 | CSTR_db_b2)) != (CSTR_db_b1 | CSTR_db_b2))
789
// b1 or b2 were absent in full list
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
795
if (disable_twins == 0 && fl1 & CSTR_db_b4)
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);
804
attr.basflg |= CSTR_bs_t; // no "not a 't'" version
807
CSTR_SetAttr(B1, &attr);
885
INT smart_diff(CSTR_rast c)
890
CSTR_GetAttr(c,&attr);
892
row = attr.row - minrow;
895
bm = (bbs3 + bbs2)/2;
897
#ifdef UFA // Valdemar 12-05-94 08:25pm
902
(abs(d1) < 2 || abs(d2) < 2) &&
906
attr.bdiff=0; // don't touch letter
907
attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
909
CSTR_SetAttr(c, &attr);
912
if(attr.h >= Ps + 2 ) // large letter
914
if(abs(d1) < 2 || abs(d2) < 2)
916
attr.bdiff=0; // don't touch letter
917
attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
918
attr.difflg |= CSTR_db_forbid;
921
{ // letter d'not lay on base
922
if( row < (bbs1+bbs2)/2 )
923
return 0; // farewell !
926
if( row+attr.h < bbs3 )
927
return 0; // farewell !
928
else if( attr.bdiff > 0 )
930
attr.bdiff=0; // don't touch letter
931
attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
938
if( attr.h < Ps-1 && (attr.flg & (CSTR_f_let | CSTR_f_bad)) )
939
// letter < Ps may be dust
941
if(abs(d1) < 2 || abs(d2) < 2)
943
attr.bdiff=0; // don't touch letter
944
attr.difflg &= ~(CSTR_db_down | CSTR_db_up);
945
attr.difflg |= CSTR_db_forbid;
949
CSTR_SetAttr(c, &attr);
955
INT HIST_STATISTIC=0;
957
extern INT hist_b3[];
958
extern INT hist_b3_f[];
960
INT GetPsFromHeights(void)
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};
971
cDefs=BPs=peak2=n_sunk=0;
972
h_size=RASTER_MAX_HEIGHT*2;
975
b1_or_b2_rong = ( abs(bbs1-bbs2) > 3 ) ? FALSE : TRUE;
980
// while( (c=c->nextl)->nextl )
981
while ( c=CSTR_GetNextRaster(c,f_letter) )
811
int16_t smart_diff(CSTR_rast c) {
812
int16_t d1, d2, bm, row;
985
815
CSTR_GetAttr(c, &attr);
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
994
n_sunk++; // sunk letter
998
CSTR_GetCollectionUni(c, &vers);
999
if( vers.lnAltCnt>0 && BracketIn(&vers) )
1000
continue; // bracket present in verses,
1003
cDefs++; // accumulate to histogramm
1007
for(i=max1=ind1=0;i < h_size; i++)
1011
max1 = Hh[i]; ind1 = i;
1018
if( ind1 < h_size-1)
1020
if( ind1 < h_size-2)
1027
ind1=flood_peak(Hh,ind1);
1029
if( cDefs>>1 > max1 )
1036
for(i=max2=ind2=0;i < h_size;i++)
1038
if(i>=ind1-4 && i<=ind1+4) continue;
1041
max2 = Hh[i]; ind2 = i;
1050
if( ind2 < h_size-1)
1053
if( ind2 < h_size-2)
1063
ind2=flood_peak(Hh,ind2);
1066
if(max2 > 0 && ( abs(ind1-ind2) >= MIN(ind1,ind2)/3) )
1069
if( max2 > 3 && peak2 )
1072
bbs1=bbs3-MAX(ind1,ind2);
1077
if( n_sunk > 2 && !b1_or_b2_rong )
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; }
1085
if( b1_or_b2_rong == FALSE )
1087
if(Ns2 > 0 && Ns2 >=Ns1)
1090
if( abs(ind1-BS2) < 3 )
1091
{ BPs=ind1; goto ret; }
1092
else if( peak2 && abs(ind2-BS2) < 3 )
1093
{ BPs=ind2; goto ret; }
1098
if( abs(ind1-BS1) < 3 )
1099
{ BPs=-ind1; goto ret; }
1100
else if( peak2 && abs(ind2-BS1) < 3 )
1101
{ BPs=-ind2; goto ret; }
1103
} // if b1 or b2 not rong
1105
if( peak2 && ind1 < ind2 )
1110
if( !peak2 && n_sunk > 0 )
1116
if((i=setup_let_case(ind1)))
1123
if( peak2 && ind2 < ind1 )
1130
// H > 30 : caps letters
1133
return ( ind1 > 30 ) ? (-ind1) : ind1 ;
1137
if(db_status & snap_activity_rbal(db_pass) )
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();
817
row = attr.row - minrow;
820
bm = (bbs3 + bbs2) / 2;
822
#ifdef UFA // Valdemar 12-05-94 08:25pm
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);
830
CSTR_SetAttr(c, &attr);
833
if (attr.h >= Ps + 2) // large letter
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 !
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);
854
if (attr.h < Ps - 1 && (attr.flg & (CSTR_f_let | CSTR_f_bad)))
855
// letter < Ps may be dust
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;
864
CSTR_SetAttr(c, &attr);
869
int16_t HIST_STATISTIC = 0;
871
extern int16_t hist_b3[];
872
extern int16_t hist_b3_f[];
874
int16_t GetPsFromHeights(void) {
879
int16_t BPs, cDefs, i, max1, max2, ind1, ind2, peak2, h_size, b_top, n_sunk,
881
int16_t Hh[RASTER_MAX_HEIGHT * 2] = { 0 };
885
cDefs = BPs = peak2 = n_sunk = 0;
886
h_size = RASTER_MAX_HEIGHT * 2;
889
b1_or_b2_rong = (abs(bbs1 - bbs2) > 3) ? FALSE : TRUE;
891
b1_or_b2_rong = FALSE;
894
// while( (c=c->nextl)->nextl )
895
while (c = CSTR_GetNextRaster(c, f_letter)) {
898
CSTR_GetAttr(c, &attr);
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
906
if (sn > attr.h >> 2)
907
n_sunk++; // sunk letter
911
CSTR_GetCollectionUni(c, &vers);
912
if (vers.lnAltCnt > 0 && BracketIn(&vers))
913
continue; // bracket present in verses,
916
cDefs++; // accumulate to histogramm
920
for (i = max1 = ind1 = 0; i < h_size; i++) {
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];
935
max1 += Hh[ind1 - 2];
939
ind1 = flood_peak(Hh, ind1);
941
if (cDefs >> 1 > max1) {
947
for (i = max2 = ind2 = 0; i < h_size; i++) {
948
if (i >= ind1 - 4 && i <= ind1 + 4)
959
max2 += Hh[ind2 - 1] * 2;
961
if (ind2 < h_size - 1)
962
max2 += Hh[ind2 + 1] * 2;
964
if (ind2 < h_size - 2)
965
max2 += Hh[ind2 + 2];
968
max2 += Hh[ind2 - 2];
973
ind2 = flood_peak(Hh, ind2);
975
if (max2 > 0 && (abs(ind1 - ind2) >= MIN(ind1, ind2) / 3))
978
if (max2 > 3 && peak2) {
979
BPs = MIN(ind1, ind2);
980
bbs1 = bbs3 - MAX(ind1, ind2);
985
if (n_sunk > 2 && !b1_or_b2_rong) {
987
TPs = def_upper_side(); // check tops
988
ds = (peak2 && ind2 < ind1) ? ind2 : ind1;
989
if (TPs > 0 && abs(TPs - ds) < 3) {
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) {
1001
} else if (peak2 && abs(ind2 - BS2) < 3) {
1007
int16_t BS1 = bbs3 - bbs1;
1008
if (abs(ind1 - BS1) < 3) {
1011
} else if (peak2 && abs(ind2 - BS1) < 3) {
1016
} // if b1 or b2 not rong
1018
if (peak2 && ind1 < ind2) {
1022
if (!peak2 && n_sunk > 0) {
1027
if ((i = setup_let_case(ind1))) {
1035
if (peak2 && ind2 < ind1) {
1041
// H > 30 : caps letters
1044
return (ind1 > 30) ? (-ind1) : ind1;
1046
ret: HIST_STATISTIC = 1;
1047
if (db_status & snap_activity_rbal(db_pass)) {
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();
1147
1058
////////////////
1149
static BYTE BracketsList[]="<>()[]";
1151
BYTE BracketIn(UniVersions *v)
1155
for(i=0 ; i<v->lnAltCnt; i++)
1157
if( memchr(BracketsList,v->Alt[i].Liga,sizeof(BracketsList)-1) )
1060
static uchar BracketsList[] = "<>()[]";
1062
uchar BracketIn(UniVersions *v) {
1065
for (i = 0; i < v->lnAltCnt; i++) {
1066
if (memchr(BracketsList, v->Alt[i].Liga, sizeof(BracketsList) - 1))
1166
INT def_upper_side(void)
1169
CSTR_rast_attr attr;
1170
INT i,max,max_sn,ind,ind_sn;
1171
WORD h_size,n_def,n_sn;
1173
INT h_top[RASTER_MAX_HEIGHT*2]={0},h_sunk[RASTER_MAX_HEIGHT*2]={0};
1175
h_size=RASTER_MAX_HEIGHT*2;
1179
// while( (c=c->nextl)->nextl )
1180
while( (c=CSTR_GetNextRaster(c, CSTR_f_let)) )
1184
// if(!(c->flg & CSTR_f_let) ) continue;
1186
CSTR_GetAttr(c, &attr);
1191
b_top=attr.row-minrow;
1192
sn=(b_top+attr.h)-(df+bbs3);
1194
if( b_top-df>=RASTER_MAX_HEIGHT*2 )
1195
continue; // Oleg : for trash lines
1197
if(abs(sn) > ((attr.h+2)/5 - 2) ) // far from b3
1211
for(i=max=ind=0;i < h_size; i++)
1213
if( max < h_top[i] )
1222
max+=h_top[ind-1]*2;
1224
max+=h_top[ind+1]*2;
1231
ind=flood_peak(h_top,ind);
1232
if( n_def>>1 > max )
1233
return FALSE; // flooded tops
1235
// find peak tops of sunked
1236
for(i=max_sn=ind_sn=0;i < h_size; i++)
1238
if( max_sn < h_sunk[i] )
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];
1253
ind_sn=flood_peak(h_sunk,ind_sn);
1255
if( !max_sn || n_sn>>1 > max_sn )
1256
return FALSE; // flooded sunk tops
1258
return ( abs(ind-ind_sn)<=3 ) ? bbs3-ind : FALSE ;
1075
int16_t def_upper_side(void) {
1077
CSTR_rast_attr attr;
1078
int16_t i, max, max_sn, ind, ind_sn;
1079
uint16_t h_size, n_def, n_sn;
1081
int16_t h_top[RASTER_MAX_HEIGHT * 2] = { 0 }, h_sunk[RASTER_MAX_HEIGHT * 2] = {
1084
h_size = RASTER_MAX_HEIGHT * 2;
1088
// while( (c=c->nextl)->nextl )
1089
while ((c = CSTR_GetNextRaster(c, CSTR_f_let))) {
1090
int16_t df, sn, b_top;
1092
// if(!(c->flg & CSTR_f_let) ) continue;
1094
CSTR_GetAttr(c, &attr);
1099
b_top = attr.row - minrow;
1100
sn = (b_top + attr.h) - (df + bbs3);
1102
if (b_top - df >= RASTER_MAX_HEIGHT * 2)
1103
continue; // Oleg : for trash lines
1105
if (abs(sn) > ((attr.h + 2) / 5 - 2)) // far from b3
1107
if (sn > attr.h >> 2) {
1108
h_sunk[b_top - df]++;
1113
h_top[b_top - df]++;
1118
for (i = max = ind = 0; i < h_size; i++) {
1119
if (max < h_top[i]) {
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];
1133
max += h_top[ind - 2];
1136
ind = flood_peak(h_top, ind);
1137
if (n_def >> 1 > max)
1138
return FALSE; // flooded tops
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]) {
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];
1156
max_sn += h_sunk[ind_sn - 2];
1160
ind_sn = flood_peak(h_sunk, ind_sn);
1162
if (!max_sn || n_sn >> 1 > max_sn)
1163
return FALSE; // flooded sunk tops
1165
return (abs(ind - ind_sn) <= 3) ? bbs3 - ind : FALSE;
1262
void tell_for_b3(INT hist_array[])
1269
if( language != LANG_RUSSIAN )
1275
bbs3=(sbs3+(Ns3>>1))/Ns3;
1277
for(i=0; i < RASTER_MAX_HEIGHT*2 ; i++)
1278
NDisp+=hist_array[i]*((i-bbs3)*(i-bbs3));
1280
ON3 = (Ns3-1)*(Ns3-1);
1281
if( 25*NDisp < ON3 ) stable_b3=TRUE;
1169
void tell_for_b3(int16_t hist_array[]) {
1171
uint32_t NDisp, ON3;
1175
if (language != LANG_RUSSIAN)
1181
bbs3 = (sbs3 + (Ns3 >> 1)) / Ns3;
1183
for (i = 0; i < RASTER_MAX_HEIGHT * 2; i++)
1184
NDisp += hist_array[i] * ((i - bbs3) * (i - bbs3));
1186
ON3 = (Ns3 - 1) * (Ns3 - 1);
1187
if (25* NDisp < ON3)
1285
1192
///////////////
1287
INT flood_peak(INT *Hh,INT ind)
1292
t=Hh[ind-2]*(ind-2);
1296
t1=Hh[ind-1]*(ind-1);
1299
Num = Hh[ind]*ind+t1+Hh[ind+1]*(ind+1)+
1300
t+Hh[ind+2]*(ind+2);
1309
Den = Hh[ind]+t1+Hh[ind+1]+t+Hh[ind+2];
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;
1198
t = Hh[ind - 2] * (ind - 2);
1203
t1 = Hh[ind - 1] * (ind - 1);
1207
Num = Hh[ind] * ind + t1 + Hh[ind + 1] * (ind + 1) + t + Hh[ind + 2] * (ind
1219
Den = Hh[ind] + t1 + Hh[ind + 1] + t + Hh[ind + 2];
1221
return ((2* Num + Den) / 2 / Den);
1315
INT is_cen_bottom_accent(BYTE c)
1317
// ����������� ������� ������� 12.09.2000 E.P.
1225
int16_t is_cen_bottom_accent(uchar c) {
1226
// ����������� ������� ������� 12.09.2000 E.P.
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 ||