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

« back to all changes in this revision

Viewing changes to cuneiform_src/Kern/usage/makeding.cpp

  • 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:
2
2
Copyright (c) 1993-2008, Cognitive Technologies
3
3
All rights reserved.
4
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
 
�������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
 
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
32
 
33
33
Redistribution and use in source and binary forms, with or without modification,
34
34
are permitted provided that the following conditions are met:
57
57
/*------------------------------------------------------------------------------------------------*/
58
58
/**
59
59
    \file   MakeDing.CPP
60
 
    \brief  ���������� ������� ��������� � ������ ������������
61
 
    \author ��������� ��������
 
60
    \brief  Реализация функций заготовки и чистки разделителей
 
61
    \author Александр Михайлов
62
62
    \date   25.04.2005
63
63
*/
64
64
/*------------------------------------------------------------------------------------------------*/
65
 
/*  N-� �������� 25.04.2005:
66
 
    - ���������� � ��������� ����������, ������������� � ������ "MakeDing.CPP" � 15.04.2002  */
 
65
/*  N-я Редакция 25.04.2005:
 
66
    - приведение к стандарту алгоритмов, реализованных в модуле "MakeDing.CPP" к 15.04.2002  */
67
67
/*------------------------------------------------------------------------------------------------*/
68
 
/**********  ���������  **********/
 
68
/**********  Заголовок  **********/
69
69
/*  Author     :  Alexander Mikhailov                                        */
70
70
/*  Last Edit  :  12.10.99                                                   */
71
71
/*  Source     :  'MakeDing.CPP'                                             */
72
 
/*  ���������� :  ������� ��������� � ������ ������������.                   */
73
 
/*  ���������� :  II � III ����� ��������� ������ ������.                    */
 
72
/*  Содержание :  Функции заготовки и чистки разделителей.                   */
 
73
/*  Назначение :  II и III этапы алгоритма поиска таблиц.                    */
74
74
/*---------------------------------------------------------------------------*/
75
75
#include <stdio.h>
76
76
#include <math.h>
82
82
#include "MakeDing.H"
83
83
/*  interface our  */
84
84
#include "skew1024.h"
85
 
/*----------    ���������� ���������    ----------------------------------------------------------*/
 
85
/*----------    Управление локальное    ----------------------------------------------------------*/
86
86
/*+ (MakeDingFromOneLine) +*/
87
 
static const int SIZE_REL_EXT_SCALE = 1024; ///< ������� ����� ������������� ����������
88
 
static const int MIN_LEN_STICK = (40 + 1); ///< ����������� ����� ������ ������������ ����� �� �����
89
 
static const int MAX_LEN_STICK = (60 - 1); ///< ������������ ����� ������ ������������ ����� �� ���.
90
 
static const int MIN_LEN_NORM_HORI = 100; ///< ����������� ����� ���������� �������������� �����
 
87
static const int SIZE_REL_EXT_SCALE = 1024; ///< масштаб шкалы относительных удлиннений
 
88
static const int MIN_LEN_STICK = (40 + 1); ///< минимальная длина ложной вертикальной линии по букве
 
89
static const int MAX_LEN_STICK = (60 - 1); ///< максимальная длина ложной вертикальной линии по бук.
 
90
static const int MIN_LEN_NORM_HORI = 100; ///< минимальная длина нормальной горизонтальной линии
91
91
/*+ (IsNearestOldDing) +*/ /*+ (IsNearestDing) +*/
92
 
/** ������������ ���������� �� ������ �������� ������� ����������� �� ������ ������ */
 
92
/** Максимальное расстояние от уровня союзного старого разделителя до острия нового */
93
93
static const int MAX_DIST_OLD_LEV_NEW_BORDER = 40;
94
 
/** ������������ ������� �������� ������� ����������� �� ����������� � ����� */
 
94
/** Максимальный недотяг союзного старого разделителя до пересечения с новым */
95
95
static const int MAX_HOLE_OLD_BORDER_NEW_LEV = 50;
96
96
/*+ (FindNextZveno) +*/
97
 
static const double HALF = .5; ///< �������� :-)
98
 
/** ������������ ���������� ����� �������� ������� ������������ */
 
97
static const double HALF = .5; ///< половина :-)
 
98
/** Максимальное расстояние между остриями союзных разделителей */
99
99
static const int MAX_DIST_FRIEND_DING_BORDER = 14;
100
100
/*+ (MakeAbsendDing) +*/
101
 
static const int EXT_DING_BORDER = 40; ///< ���������� ����� �����������
 
101
static const int EXT_DING_BORDER = 40; ///< удлиннение конца разделителя
102
102
/*+ (MakeAllAbsendDing) +*/
103
 
static const int MIN_LEN_BASIS_DING = 184; ///< ����������� ����� �������� �����������
 
103
static const int MIN_LEN_BASIS_DING = 184; ///< минимальная длина опорного разделителя
104
104
/*+ (DelFreeDing) +*/
105
 
/** ������������ ������� ����������� �� ����������� � ��������� */
 
105
/** Максимальный недотяг разделителя до пересечения с ближайшим */
106
106
static const int MAX_HOLE_BORDER_NEAREST_LEV = 10;
107
107
/*+ (JoinDoubleDing) +*/
108
 
/** ������������ ���������� ����� �������������� ������������� */
 
108
/** Максимальное расстояние между дублирующимися разделителями */
109
109
static const int MAX_DIST_DOUBLE_DING = 10;
110
 
/*----------    ��������� �������    -------------------------------------------------------------*/
 
110
/*----------    Локальные функции    -------------------------------------------------------------*/
111
111
/**
112
 
    \brief ������� ������������ ����������� �� �����
113
 
    \param pDing [out] - ��������� �� �����������
114
 
    \param Skew[in]    - ���� ������� ��������� ���������
115
 
    \param pLine [in]  - ��������� �� �����
116
 
    \param Hori [in]   - �������������� �� ����� ��������������
117
 
    \param pParam [in] - ��������� �� ��������� ����������
 
112
    \brief Функция изготовления разделителя из линии
 
113
    \param pDing [out] - указатель на разделитель
 
114
    \param Skew[in]    - угол наклона идеальных координат
 
115
    \param pLine [in]  - указатель на линию
 
116
    \param Hori [in]   - горизонтальная ли линия обрабатывается
 
117
    \param pParam [in] - указатель на параметры управления
118
118
*/
119
119
static void MakeDingFromOneLine (RLT_DING *pDing, const int Skew, const RLT_LINE *pLine
120
120
    , const bool Hori, const RLT_PARAM *pParam)
121
121
{
122
122
    Point16 A = {0}, B = {0};
123
123
    pDing->Width = pLine->Wid;
124
 
    if (pLine->Type & RLT_LT_Line)//����� - ����� ���������
 
124
    if (pLine->Type & RLT_LT_Line)//сырьё - линия разграфки
125
125
    {
126
126
        pDing->Type  = RLT_DT_Line;
127
127
        if (pLine->Type & RLT_LT_Pointed)
129
129
        if (pLine->Type & RLT_LT_Doubt)
130
130
            pDing->Type  |= RLT_DT_Doubt;//26.04.01
131
131
    }
132
 
    else//����� - ����������� ������
 
132
    else//сырьё - межстрочная полоса
133
133
    {
134
134
        if (pLine->Type & RLT_LT_Ssel)
135
135
            pDing->Type  = RLT_DT_Ssel;
136
136
        else
137
137
            pDing->Type  = RLT_DT_Unknown;
138
138
    }
139
 
    /*  ������������� ����������  */
 
139
    /*  Устанавливаем удлиннение  */
140
140
    int Udl = (pLine->Len * pParam->MaxRelUdlDng + SIZE_REL_EXT_SCALE / 2) / SIZE_REL_EXT_SCALE;
141
141
    if ((!Hori) && (pLine->Len >= MIN_LEN_STICK) && (pLine->Len <= MAX_LEN_STICK))
142
142
        Udl = pParam->MaxAbsUdlDng;
155
155
    B.y = pLine->End.y;
156
156
    ::Deskew (A, -Skew);
157
157
    ::Deskew (B, -Skew);
158
 
    if (Hori)//��������������
 
158
    if (Hori)//горизонтальные
159
159
    {
160
160
        pDing->Beg = A.x;
161
161
        pDing->End = B.x;
163
163
        pDing->End_Big = B.x + Udl;
164
164
        pDing->Level = A.y + B.y;
165
165
    }
166
 
    else//������������
 
166
    else//вертикальные
167
167
    {
168
168
        pDing->Beg = A.y;
169
169
        pDing->End = B.y;
178
178
}
179
179
/*------------------------------------------------------------------------------------------------*/
180
180
/**
181
 
    \brief ������� ���������, ���������� �� ������ �����������, ������� � ����� ������������
182
 
    \param pD [out]    - ������ ������������
183
 
    \param nD [out]    - ���������� ������������
184
 
    \param Level [out] - ��������� ����� ������������ �����������
185
 
    \param Pos [out]   - ������� ������������ �����������
186
 
    \retval bool       - ���������� ��� ���
 
181
    \brief Функция проверяет, существует ли старый разделитель, близкий к торцу создаваемого
 
182
    \param pD [out]    - массив разделителей
 
183
    \param nD [out]    - количество разделителей
 
184
    \param Level [out] - положение торца создаваемого разделителя
 
185
    \param Pos [out]   - уровень создаваемого разделителя
 
186
    \retval bool       - существует или нет
187
187
*/
188
188
static bool IsNearestOldDing (const RLT_DING *pD, const int nD, const int Level, const int Pos)
189
189
{
201
201
}
202
202
/*------------------------------------------------------------------------------------------------*/
203
203
/**
204
 
    \brief ������� ���������, ���������� �� ������ �����������, ������� � ����� ������������
205
 
    \param pD [out]    - ������ ������������
206
 
    \param nD [out]    - ���������� ������������
207
 
    \param Level [out] - ������� ������������ �����������
208
 
    \param Beg [out]   - ��������� ������ ������������ �����������
209
 
    \param End [out]   - ��������� ����� ������������ �����������
210
 
    \retval bool       - ���������� ��� ���
 
204
    \brief Функция проверяет, существует ли старый разделитель, близкий к торцу создаваемого
 
205
    \param pD [out]    - массив разделителей
 
206
    \param nD [out]    - количество разделителей
 
207
    \param Level [out] - уровень создаваемого разделителя
 
208
    \param Beg [out]   - положение начала создаваемого разделителя
 
209
    \param End [out]   - положение конца создаваемого разделителя
 
210
    \retval bool       - существует или нет
211
211
*/
212
 
static bool IsNearestDing (const RLT_DING *pD, const int nD, const Int32 Level, const Int32 Beg
213
 
    , const Int32 End)
 
212
static bool IsNearestDing (const RLT_DING *pD, const int nD, const int32_t Level, const int32_t Beg
 
213
    , const int32_t End)
214
214
{
215
215
    for (int i = 0;  i < nD;  i++)
216
216
    {
226
226
}
227
227
/*------------------------------------------------------------------------------------------------*/
228
228
/**
229
 
    \brief ������� ���������� �� ����������� ����� � �������� (�� ����������� �������)
230
 
    \param p_Mas [in/out] - ����� �����
231
 
    \param p_Ind [in/out] - ����� ��������
232
 
    \param n [in]         - ����������� �������
 
229
    \brief Функция сортировки по возрастанию весов и индексов (не пузырьковым методом)
 
230
    \param p_Mas [in/out] - масив весов
 
231
    \param p_Ind [in/out] - масив индексов
 
232
    \param n [in]         - размерность массива
233
233
*/
234
234
static void MyISort (int *p_Mas, int *p_Ind, const int n)
235
235
{
236
 
    for (int i = 0;  i < n - 1;  i++)//����������� �� ���������� �����
 
236
    for (int i = 0;  i < n - 1;  i++)//расстановка на правильное место
237
237
    {
238
 
        for (int j = i + 1;  j < n;  j++)//����� ����������� �������
 
238
        for (int j = i + 1;  j < n;  j++)//ловля нарушителей впереди
239
239
        {
240
240
            if (p_Mas[i] <= p_Mas[j])
241
241
                continue;
250
250
}
251
251
/*------------------------------------------------------------------------------------------------*/
252
252
/**
253
 
    \brief ������� ��������� ������� ������� ������������
254
 
    \param p_Mas [in/out]    - ����� ������ ������� ������������
255
 
    \param p_Row [in/out]    - ����� ������� ������� ������������
256
 
    \param n [in]            - ����������� �������
257
 
    \param p_i0 [in/out]     - ��������� �� ������, �� ������� �������� ������� ����������� �� ����
258
 
    \param p_Level [out]     - ������� ���������� �������� �����������
259
 
    \param p_Beg [out]       - ������ ���������� �������� �����������
260
 
    \param p_End [out]       - ����� ���������� �������� �����������
261
 
    \param MinVoiForCre [in] - ����������� ����� ������� �� �������� ������ �����������
262
 
    \retval bool             - ������� ��� ���
 
253
    \brief Функция выявления краевых неявных разделителей
 
254
    \param p_Mas [in/out]    - масив концов опорных разделителей
 
255
    \param p_Row [in/out]    - масив уровней опорных разделителей
 
256
    \param n [in]            - размерность массива
 
257
    \param p_i0 [in/out]     - указатель на индекс, по который смотреть опорные разделители не надо
 
258
    \param p_Level [out]     - уровень найденного будущего разделителя
 
259
    \param p_Beg [out]       - начало найденного будущего разделителя
 
260
    \param p_End [out]       - конец найденного будущего разделителя
 
261
    \param MinVoiForCre [in] - минимальное число голосов за создание нового разделителя
 
262
    \retval bool             - выявили или нет
263
263
*/
264
264
static bool FindNextZveno (int *p_Mas, int *p_Row, const int n, int *p_i0, int *p_Level, int *p_Beg
265
265
    , int *p_End, const int MinVoiForCre)
266
266
{
267
 
    /*  ����� ���������  */
268
 
    for (int i = *p_i0 + 1;  i < n - 1;  i++)//���� ������ ����������� � ���������� �������
 
267
    /*  поиск скоплений  */
 
268
    for (int i = *p_i0 + 1;  i < n - 1;  i++)//ищем первый разделитель с синхронной связкой
269
269
    {
270
270
        int Wid = 1;
271
271
        int Sum = p_Mas[i];
272
 
        int iFin = 0; //�������� ������� (!)
273
 
        for (int j = i + 1;  j < n;  j++)//���� ���������� ���������
 
272
        int iFin = 0; //стандарт требует (!)
 
273
        for (int j = i + 1;  j < n;  j++)//ищем синхронных товарищей
274
274
        {
275
275
            if (abs (p_Mas[i] - p_Mas[j]) > MAX_DIST_FRIEND_DING_BORDER)
276
276
                break;
278
278
            Sum += p_Mas[j];
279
279
            iFin = j;
280
280
        }
281
 
        if (Wid < MinVoiForCre)//���������� ������
 
281
        if (Wid < MinVoiForCre)//слабоватая связка
282
282
            continue;
283
283
        *p_i0 = iFin;
284
284
        *p_Beg = p_Row[i];
285
285
        *p_End = p_Row[i];
286
 
        for (j = i + 1;  j <= iFin;  j++)//���� ����� ������� ������ �� ������ (!) � ������
 
286
        for (j = i + 1;  j <= iFin;  j++)//ищем самые крайние уровни не только (!) в связке
287
287
        {
288
288
            if (*p_Beg > p_Row[j])
289
 
                *p_Beg = p_Row[j];//������ ������� �� �����������
 
289
                *p_Beg = p_Row[j];//должно никогда не срабатывать
290
290
            if (*p_End < p_Row[j])
291
291
                *p_End = p_Row[j];
292
292
        }
300
300
}
301
301
/*------------------------------------------------------------------------------------------------*/
302
302
/**
303
 
    \brief ������� ������������ ���������� �����������
304
 
    \param pD [out]   - ��������� �� �����������
305
 
    \param Level [in] - ������� �����������
306
 
    \param Beg [in]   - ������ �����������
307
 
    \param End [in]   - ����� �����������
 
303
    \brief Функция изготовления требуемого разделителя
 
304
    \param pD [out]   - указатель на разделитель
 
305
    \param Level [in] - уровень разделителя
 
306
    \param Beg [in]   - начало разделителя
 
307
    \param End [in]   - конец разделителя
308
308
*/
309
 
static void MakeAbsendDing (RLT_DING *pD, const Int32 Level, const Int32 Beg, const Int32 End)
 
309
static void MakeAbsendDing (RLT_DING *pD, const int32_t Level, const int32_t Beg, const int32_t End)
310
310
{
311
311
    pD->Beg = Beg;
312
312
    pD->End = End;
318
318
}
319
319
/*------------------------------------------------------------------------------------------------*/
320
320
/**
321
 
    \brief ������� ������������ ���� ������������� (?) ������� ������������
322
 
    \param pD1 [out]         - ����������� ������ ������������
323
 
    \param nD1 [in]          - ���������� ������������ � ����������� ������� �� ����������
324
 
    \param pD2 [out]         - ������������� ������ ������������
325
 
    \param nD2 [in]          - ���������� ������������ � ������������� �������
326
 
    \param p_Stat1 [out]     - ������ ������� � ����������� ������� ������������
327
 
    \param p_n1 [in/out]     - ������� ���������� ������������ � ����������� �������
328
 
    \param FromBeg [in]      - �� ������ �� ����������� �����
329
 
    \param MinVoiForCre [in] - ����������� ����� ������� �� �������� ������ �����������
330
 
    \param MinLenOpory [in]  - ����������� ����� �������� ����������� (�� ���������) (!)
 
321
    \brief Функция изготовления всех отсутствующих (?) неявных разделителей
 
322
    \param pD1 [out]         - пополняемый массив разделителей
 
323
    \param nD1 [in]          - количество разделителей в пополняемом массиве до пополнения
 
324
    \param pD2 [out]         - ортогональный массив разделителей
 
325
    \param nD2 [in]          - количество разделителей в ортогональном массиве
 
326
    \param p_Stat1 [out]     - массив пометок о пополняемом массиве разделителей
 
327
    \param p_n1 [in/out]     - текущее количество разделителей в пополняемом массиве
 
328
    \param FromBeg [in]      - на начало ли разделителя опора
 
329
    \param MinVoiForCre [in] - минимальное число голосов за создание нового разделителя
 
330
    \param MinLenOpory [in]  - минимальная длина опорного разделителя (от заказчика) (!)
331
331
*/
332
332
static void MakeAllAbsendDing (RLT_DING *pD1, const int nD1, const RLT_DING *pD2, const int nD2
333
333
    , char *p_Stat1, int *p_n1, bool const FromBeg, const int MinVoiForCre, const int MinLenOpory)
334
334
{
335
335
    int Mas[MaxMyDings], Row[MaxMyDings];
336
336
    int kD2 = 0;
337
 
    if (FromBeg)//����� �� ������ �� �����������
 
337
    if (FromBeg)//опора на начало ли разделителя
338
338
    {
339
 
        for (int i = 0;  i < nD2;  i++)//�������� ������� �����������
 
339
        for (int i = 0;  i < nD2;  i++)//набираем опорные разделители
340
340
        {
341
341
            if (pD2[i].Type & RLT_DT_Refused)
342
342
                continue;
353
353
            kD2++;
354
354
        }
355
355
    }
356
 
    else//����� �� ����� �����������
 
356
    else//опора на конец разделителя
357
357
    {
358
 
        for (int i = 0;  i < nD2;  i++)//�������� ������� �����������
 
358
        for (int i = 0;  i < nD2;  i++)//набираем опорные разделители
359
359
        {
360
360
            if (pD2[i].Type & RLT_DT_Refused)
361
361
                continue;
372
372
            kD2++;
373
373
        }
374
374
    }
375
 
    MyISort (Row, Mas, kD2);//��������� �� ����������� ������
 
375
    MyISort (Row, Mas, kD2);//сортируем по возрастанию уровня
376
376
    int i = -1;
377
 
    int Beg = 0, End = 0, Level = 0;//������� ���������������� �����������
378
 
    while (1)//����������� �����, ���� ����������
 
377
    int Beg = 0, End = 0, Level = 0;//реально инициализируются непрозрачно
 
378
    while (1)//изготовляем новые, пока получается
379
379
    {
380
380
        bool ret = FindNextZveno (Mas, Row, kD2, &i, &Level, &Beg, &End, MinVoiForCre);
381
381
        if (!ret)
383
383
        ret = IsNearestDing (pD1, nD1, Level, Beg, End);
384
384
        if (ret)
385
385
            continue;
386
 
        if (*p_n1 >= MaxMyDings)//������������� ������ (!)
387
 
            continue;  // �����! �� ���� ������� ������
 
386
        if (*p_n1 >= MaxMyDings)//Зацикливанием пахнет (!)
 
387
            continue;  // грязь! не могу создать нужный
388
388
        MakeAbsendDing (&(pD1[*p_n1]), Level, Beg, End);
389
389
        p_Stat1[*p_n1] = RLT_DS_Created;
390
390
        (*p_n1)++;
392
392
}
393
393
/*------------------------------------------------------------------------------------------------*/
394
394
/**
395
 
    \brief ������� ��������� � ��������� ������� ����������� ������������
396
 
    \param pD1 [in]      - ����������� ������ ������������
397
 
    \param nD1 [in]      - ���������� ������������ � ����������� �������
398
 
    \param pD2 [in]      - ������������� ������ ������������
399
 
    \param nD2 [in]      - ���������� ������������ � ������������� �������
400
 
    \param p_Stat1 [out] - ������ ������� � ����������� ������� ������������
 
395
    \brief Функция выявления и отмечания одиноко болтающихся разделителей
 
396
    \param pD1 [in]      - проверяемый массив разделителей
 
397
    \param nD1 [in]      - количество разделителей в проверяемом массиве
 
398
    \param pD2 [in]      - ортогональный массив разделителей
 
399
    \param nD2 [in]      - количество разделителей в ортогональном массиве
 
400
    \param p_Stat1 [out] - массив пометок о пополняемом массиве разделителей
401
401
*/
402
402
static void DelFreeDing (const RLT_DING *pD1, const int nD1, const RLT_DING *pD2, const int nD2
403
403
    , char *p_Stat1)
404
404
{
405
 
    for (int i = 0;  i < nD1; i++)//���������� ����������� �����������
 
405
    for (int i = 0;  i < nD1; i++)//перебираем проверяемые разделители
406
406
    {
407
407
        bool NeedDel = true;
408
 
        for (int j = 0;  j < nD2;  j++)//���� ������������� �����������
 
408
        for (int j = 0;  j < nD2;  j++)//ищем ортогональный цепляющийся
409
409
        {
410
410
            if (pD1[i].Beg_Big > pD2[j].Level + MAX_HOLE_BORDER_NEAREST_LEV)
411
411
                continue;
424
424
}
425
425
/*------------------------------------------------------------------------------------------------*/
426
426
/**
427
 
    \brief ������� ���������, �������� �� ���� ������������ ������, � ���� ��, �� ������ ������
428
 
    \param pD [out]      - ������ ������������
429
 
    \param p_nD [in/out] - ���������� ������������ � �������
430
 
    \param p_Stat [out]  - ������ ������� � ������� ������������
431
 
    \param pForw [out]   - ������ ������� �� �������� ������������
432
 
    \param MyMaxL [in]   - ������������ ���������� ������������ ��� ������������ �� ��������
433
 
    \param StepAlg [in]  - ����� ������������� ����
434
 
    \param Shft [in]     - ����� ������ ������������� ������� ��� ������ �������
435
 
    \param i [in]        - ����� ������� �����������
436
 
    \param j [in]        - ����� ������� �����������
437
 
    \retval bool         - ������������ ������ �������
 
427
    \brief Функция проверяет, является ли пара разделителей дублем, и если да, то создаёт единый
 
428
    \param pD [out]      - массив разделителей
 
429
    \param p_nD [in/out] - количество разделителей в массиве
 
430
    \param p_Stat [out]  - массив пометок о массиве разделителей
 
431
    \param pForw [out]   - массив пометок об эволюции разделителей
 
432
    \param MyMaxL [in]   - максимальное количество разделителей для отслеживания их эволюции
 
433
    \param StepAlg [in]  - номер эволюционного шага
 
434
    \param Shft [in]     - сдвиг внутри эволюционного массива для записи событий
 
435
    \param i [in]        - номер первого разделителя
 
436
    \param j [in]        - номер второго разделителя
 
437
    \retval bool         - корректность работы функции
438
438
*/
439
439
static bool JoinDoubleDing (RLT_DING *pD, int *p_nD, char *p_Stat, int *pForw, const int MyMaxL
440
440
    , const int StepAlg, const int Shft, const int i, const int j)
448
448
    if ((pD[i].Beg_Big > pD[j].End) && (pD[i].Beg > pD[j].End_Big))
449
449
        return true;
450
450
    //09.11.01
451
 
    if ((pD[i].Type == RLT_DT_Line) && (pD[j].Type == RLT_DT_Line))//��������� ������� �����
 
451
    if ((pD[i].Type == RLT_DT_Line) && (pD[j].Type == RLT_DT_Line))//настоящие двойные линии
452
452
    {
453
453
        if ((pD[j].Beg > pD[i].Beg) && (pD[j].Beg_Big < pD[i].Beg))
454
454
            return true;
458
458
    //////////
459
459
    if (*p_nD >= MaxMyDings)
460
460
        return false;
461
 
    /*  ������ ����������  */
 
461
    /*  Решили объединять  */
462
462
    p_Stat[i] = RLT_DS_WasChanged;
463
463
    p_Stat[j] = RLT_DS_WasChanged;
464
464
    p_Stat[*p_nD] = RLT_DS_MadeOnBase;
495
495
        Wei_i = 0;
496
496
    if (Wei_j < 0)
497
497
        Wei_j = 0;
498
 
    int Level = 0; //�������� ������� (!)
 
498
    int Level = 0; //стандарт требует (!)
499
499
    if ((Wei_i == 0) && (Wei_j == 0))
500
500
        Level = (pD[i].Level + pD[j].Level) / 2;
501
501
    else//15.04.02-End
502
502
        Level = (Wei_i * pD[i].Level + Wei_j * pD[j].Level) / (Wei_i + Wei_j);
503
503
    pD[*p_nD].Level = Level;
504
504
    //15.04.02-Beg
505
 
    int Width = 0; //�������� ������� (!)
 
505
    int Width = 0; //стандарт требует (!)
506
506
    if ((Wei_i == 0) && (Wei_j == 0))
507
507
        Width = (pD[i].Width + pD[j].Width) / 2;
508
508
    else//15.04.02-End
511
511
    (*p_nD)++;
512
512
    return true;
513
513
}
514
 
/*----------    ���������� �������    ------------------------------------------------------------*/
 
514
/*----------    Переходные функции    ------------------------------------------------------------*/
515
515
void EvolFor_MakeDing (const RLT_LINEPOOL *pLinePool, int *pForw, int *pBack, const int MyMaxL
516
516
    , const int StepAlg)
517
517
{
518
518
    RLT_LINE *pL = pLinePool->pLine;
519
519
    int nHori = 0;
520
520
    int nVert = 0;
521
 
    for (int i = 0;  i < pLinePool->nLine;  i++)//���������� �����
 
521
    for (int i = 0;  i < pLinePool->nLine;  i++)//перебираем линии
522
522
    {
523
523
        if ((pL[i].Type & RLT_LT_SkewConflict) == RLT_LT_SkewConflict)
524
524
            continue;
525
525
        int Sect = ::LineSect (pL[i].Type);
526
 
        switch (Sect)//������ �������� ���� ����� �����
 
526
        switch (Sect)//запись эволюции двух типов линий
527
527
        {
528
 
            case RLT_LDIR_Horiz ://��������������
 
528
            case RLT_LDIR_Horiz ://горизонтальные
529
529
                pForw[(2 * MyMaxL * StepAlg) + i] = nHori;
530
530
                pBack[(2 * MyMaxL * StepAlg) + nHori] = i;
531
531
                nHori++;
532
532
                break;
533
 
            case RLT_LDIR_Verti ://������������
 
533
            case RLT_LDIR_Verti ://вертикальные
534
534
                pForw[(2 * MyMaxL * StepAlg) + MyMaxL + i] = MyMaxL + nVert;
535
535
                pBack[(2 * MyMaxL * StepAlg) + MyMaxL + nVert] = MyMaxL + i;
536
536
                nVert++;
542
542
}
543
543
/*------------------------------------------------------------------------------------------------*/
544
544
bool MakeDingFromLine (RLT_DINGPOOL *pDingPool, const RLT_LINEPOOL *pLinePool
545
 
    , const RLT_PARAM *pParam, const Int32 SkewReg)
 
545
    , const RLT_PARAM *pParam, const int32_t SkewReg)
546
546
{
547
547
//    RLT_LINEATDIR *pP;
548
548
    RLT_LINE *pL = pLinePool->pLine;
549
549
//    pP = pLinePool->Pool;
550
550
    pDingPool->Skew = SkewReg;
551
 
    /*  ������� �����������  */
 
551
    /*  Создаем разделители  */
552
552
    pDingPool->nHori = 0;
553
553
    pDingPool->nVert = 0;
554
 
    for (int i = 0;  i < pLinePool->nLine; i++)//���������� �����
 
554
    for (int i = 0;  i < pLinePool->nLine; i++)//перебираем линии
555
555
    {
556
556
        if ((pL[i].Type & RLT_LT_SkewConflict) == RLT_LT_SkewConflict)
557
557
            continue;
558
558
        int Sect = ::LineSect (pL[i].Type);
559
 
        switch (Sect)//������ ����������� ���� ����� �����
 
559
        switch (Sect)//делаем разделители двух типов линий
560
560
        {
561
 
            case RLT_LDIR_Horiz ://��������������
 
561
            case RLT_LDIR_Horiz ://горизонтальные
562
562
                if (pDingPool->nHori >= MaxMyDings)
563
563
                    return false;
564
564
                pDingPool->HoriStat[pDingPool->nHori] = RLT_DS_Normal;
566
566
                    , true, pParam);
567
567
                (pDingPool->nHori)++;
568
568
                break;
569
 
            case RLT_LDIR_Verti ://������������
 
569
            case RLT_LDIR_Verti ://вертикальные
570
570
                if (pDingPool->nVert >= MaxMyDings)
571
571
                    return false;
572
572
                pDingPool->VertStat[pDingPool->nVert] = RLT_DS_Normal;
585
585
    , const int StepAlg, const RLT_REVIDING *pReviDing)
586
586
{
587
587
//    Rect32 Bound, Found;
588
 
    /*  ������� ��������� ������� ������� ������������  */
 
588
    /*  Находим уверенные границы области разделителей  */
589
589
//    FindBoundsOfDingRegion (pDingPool, &Bound, &Found);
590
590
//    if (!(Found.left&&Found.right&&Found.top&&Found.bottom))
591
591
//        return FALSE;
592
 
    /*  ��������� ����������� ����������� �� ����� �������  */
 
592
    /*  Добавляем недостающие разделители по краям области  */
593
593
//    AddAbsendDingForBound (pDingPool, &Bound);
594
594
    int nHori = pDingPool->nHori;
595
595
    int nVert = pDingPool->nVert;
596
 
    /*  ����������� �������� ���������  */
 
596
    /*  тривиальная эволюция имеющихся  */
597
597
    for (int i = 0;  i < 2 * MyMaxL;  i++)
598
598
    {
599
599
        pForw[(2*MyMaxL*StepAlg) + i] = i;
600
600
        pBack[(2*MyMaxL*StepAlg) + i] = i;
601
601
    }
602
 
    /*  ������� ����������� �������������� �� �������  */
 
602
    /*  создаем недостающие горизонтальные по началам  */
603
603
    MakeAllAbsendDing (pDingPool->Hori, nHori, pDingPool->Vert, nVert
604
604
        , pDingPool->HoriStat, &(pDingPool->nHori), true, pReviDing->MinVoiForCre
605
605
        , pReviDing->VerMinLenOpory);
606
 
    /*  ������� ����������� �������������� �� ������  */
 
606
    /*  создаем недостающие горизонтальные по концам  */
607
607
    MakeAllAbsendDing (pDingPool->Hori, nHori, pDingPool->Vert, nVert
608
608
        , pDingPool->HoriStat, &(pDingPool->nHori), false, pReviDing->MinVoiForCre
609
609
        , pReviDing->VerMinLenOpory);
610
 
    /*  ������� ����������� ������������ �� �������  */
 
610
    /*  создаем недостающие вертикальные по началам  */
611
611
    MakeAllAbsendDing (pDingPool->Vert, nVert, pDingPool->Hori, nHori
612
612
        , pDingPool->VertStat, &(pDingPool->nVert), true, pReviDing->MinVoiForCre
613
613
        , pReviDing->HorMinLenOpory);
614
 
    /*  ������� ����������� ������������ �� ������  */
 
614
    /*  создаем недостающие вертикальные по концам  */
615
615
    MakeAllAbsendDing (pDingPool->Vert, nVert, pDingPool->Hori, nHori
616
616
        , pDingPool->VertStat, &(pDingPool->nVert), false, pReviDing->MinVoiForCre
617
617
        , pReviDing->HorMinLenOpory);
618
 
    /*  ������� ��������� �������������� �����������  */
 
618
    /*  Удаляем свободные горизонтальные разделители  */
619
619
    DelFreeDing (pDingPool->Hori, pDingPool->nHori, pDingPool->Vert, pDingPool->nVert
620
620
        , pDingPool->HoriStat);
621
 
    /*  ������� ��������� ������������ �����������  */
 
621
    /*  Удаляем свободные вертикальные разделители  */
622
622
    DelFreeDing (pDingPool->Vert, pDingPool->nVert, pDingPool->Hori, pDingPool->nHori
623
623
        , pDingPool->VertStat);
624
 
    /*  �������� ������������� �������������� �����������  */
 
624
    /*  Слепляем дублирующиеся горизонтальные разделители  */
625
625
    for (i = 0;  i < pDingPool->nHori;  i++)
626
626
    {
627
627
        if (pDingPool->HoriStat[i] != RLT_DS_Normal)
628
628
            continue;
629
 
        for (int j = i + 1;  j < pDingPool->nHori;  j++)//���������� ����������
 
629
        for (int j = i + 1;  j < pDingPool->nHori;  j++)//перебираем напарников
630
630
        {
631
631
            bool ret = JoinDoubleDing (pDingPool->Hori, &pDingPool->nHori, pDingPool->HoriStat
632
632
                , pForw, MyMaxL, StepAlg, 0, i, j);
634
634
                return false;
635
635
        }
636
636
    }
637
 
    /*  �������� ������������� ������������ �����������  */
 
637
    /*  Слепляем дублирующиеся вертикальные разделители  */
638
638
    for (i = 0;  i < pDingPool->nVert;  i++)
639
639
    {
640
640
        if (pDingPool->VertStat[i] != RLT_DS_Normal)
641
641
            continue;
642
 
        for (int j = i + 1;  j < pDingPool->nVert;  j++)//���������� ����������
 
642
        for (int j = i + 1;  j < pDingPool->nVert;  j++)//перебираем напарников
643
643
        {
644
644
            bool ret = JoinDoubleDing (pDingPool->Vert, &pDingPool->nVert, pDingPool->VertStat
645
645
                , pForw, MyMaxL, StepAlg, MyMaxL, i, j);
650
650
    return true;
651
651
}
652
652
/*------------------------------------------------------------------------------------------------*/
653
 
/*----------    ��������� �������    -------------------------------------------------------------*/
 
653
/*----------    Локальные функции    -------------------------------------------------------------*/
654
654
static void MakeDingFromOneLine (RLT_DING *pDing, const int Skew, const RLT_LINE *pLine
655
655
    , const bool Hori, const RLT_PARAM *pParam);
656
656
static bool IsNearestOldDing (const RLT_DING *pD, const int nD, const int Level, const int Pos);
657
 
static bool IsNearestDing (const RLT_DING *pD, const int nD, const Int32 Level, const Int32 Beg
658
 
    , const Int32 End);
 
657
static bool IsNearestDing (const RLT_DING *pD, const int nD, const int32_t Level, const int32_t Beg
 
658
    , const int32_t End);
659
659
static void MyISort (int *p_Mas, int *p_Ind, const int n);
660
660
static bool FindNextZveno (int *p_Mas, int *p_Row, const int n, int *p_i0, int *p_Level, int *p_Beg
661
661
    , int *p_End, const int MinVoiForCre);
662
 
static void MakeAbsendDing (RLT_DING *pD, const Int32 Level, const Int32 Beg, const Int32 End);
 
662
static void MakeAbsendDing (RLT_DING *pD, const int32_t Level, const int32_t Beg, const int32_t End);
663
663
static void MakeAllAbsendDing (RLT_DING *pD1, const int nD1, const RLT_DING *pD2, const int nD2
664
664
    , char *p_Stat1, int *p_n1, bool const FromBeg, const int MinVoiForCre, const int MinLenOpory);
665
665
static void DelFreeDing (const RLT_DING *pD1, const int nD1, const RLT_DING *pD2, const int nD2