2
Copyright (c) 1993-2008, Cognitive Technologies
5
ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ ļæ½ ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½,
6
ļæ½ļæ½ļæ½ ļæ½ ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½, ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½, ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½:
8
* ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½
9
ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½, ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½
10
ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½.
11
* ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½/ļæ½ļæ½ļæ½ ļæ½
12
ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½, ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½, ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½
13
ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½, ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½
14
ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½.
15
* ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ Cognitive Technologies, ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½
16
ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½/ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½
17
ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½, ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½, ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½
18
ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½.
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.
59
/****************************************************************************
61
* P A G E L A Y O U T *
63
* Written in 1991 by Yuri Panchul *
65
* LTREMOVE.C - Blocks removing *
67
***************************************************************************/
79
extern Handle hRemoveEmptyBlocks;
82
/****************************************************************************
86
* Blocks removing with Pictures data *
88
* Heuristic: If block is small and is surrounded by picture *
89
* at least from three directions, this block should be removed. *
91
***************************************************************************/
93
# define MIN_DISTANCE 0
94
# define MAX_DISTANCE 3
95
# define N_LAYERS (MAX_DISTANCE - MIN_DISTANCE + 1)
97
# define N_DIRECTIONS 4
105
char *apDirName [N_DIRECTIONS] = { "Left ", "Top ", "Right ", "Bottom" };
115
static DIRECTION Dirs [N_DIRECTIONS];
117
static int PassHorzInterval (int y, int x1, int x2)
122
if (y < 0 || y >= PAGE_MATRIX_HEIGHT)
126
EXCHANGE_INTS (x1, x2);
128
if (x1 >= PAGE_MATRIX_WIDTH)
134
if (x2 >= PAGE_MATRIX_WIDTH)
135
x2 = PAGE_MATRIX_WIDTH - 1;
139
for (p = PageMatrix + (y << PAGE_MATRIX_WIDTH_SHIFT) + x1;
140
p <= PageMatrix + (y << PAGE_MATRIX_WIDTH_SHIFT) + x2;
143
if (*p & PMC_PICTURE)
150
static int PassVertInterval (int x, int y1, int y2)
155
if (x < 0 || x >= PAGE_MATRIX_WIDTH)
159
EXCHANGE_INTS (y1, y2);
161
if (y1 >= PAGE_MATRIX_HEIGHT)
167
if (y2 >= PAGE_MATRIX_HEIGHT)
168
y2 = PAGE_MATRIX_HEIGHT - 1;
172
for (p = PageMatrix + (y1 << PAGE_MATRIX_WIDTH_SHIFT) + x;
173
p <= PageMatrix + (y2 << PAGE_MATRIX_WIDTH_SHIFT) + x;
174
p += PAGE_MATRIX_WIDTH)
176
if (*p & PMC_PICTURE)
183
static int CompDirsPictureDensity (const DIRECTION *p,
186
if (p -> nWidth == 0 || q -> nWidth == 0)
187
ErrorInternal ("p -> nWidth == 0 || q -> nWidth == 0 !");
189
return (q -> nPictureSquare * p -> nWidth
190
- p -> nPictureSquare * q -> nWidth);
193
static RECTANGLE rMatrix;
196
static RECTANGLE rBoundary;
197
static BYTE *pFirstLine, *pLastLine, *pLine, *p;
199
void PrepareDebugPictureOutput (void)
201
pFirstLine = PageMatrix + (rMatrix.yTop << PAGE_MATRIX_WIDTH_SHIFT);
202
pLastLine = PageMatrix + (rMatrix.yBottom << PAGE_MATRIX_WIDTH_SHIFT);
204
for (pLine = pFirstLine; pLine <= pLastLine; pLine += PAGE_MATRIX_WIDTH)
206
for (p = pLine + rMatrix.xLeft; p <= pLine + rMatrix.xRight; p++)
213
MAX (0, rMatrix.xLeft - MAX_DISTANCE);
215
MIN (PAGE_MATRIX_WIDTH - 1, rMatrix.xRight + MAX_DISTANCE);
217
MAX (0, rMatrix.yTop - MAX_DISTANCE);
219
MIN (PAGE_MATRIX_HEIGHT - 1, rMatrix.yBottom + MAX_DISTANCE);
221
pFirstLine = PageMatrix + (rBoundary.yTop << PAGE_MATRIX_WIDTH_SHIFT);
222
pLastLine = PageMatrix + (rBoundary.yBottom << PAGE_MATRIX_WIDTH_SHIFT);
224
for (pLine = pFirstLine; pLine <= pLastLine; pLine += PAGE_MATRIX_WIDTH)
226
for (p = pLine + rBoundary.xLeft;
227
p <= pLine + rBoundary.xRight;
235
void UnPrepareDebugPictureOutput (void)
237
for (pLine = pFirstLine; pLine <= pLastLine; pLine += PAGE_MATRIX_WIDTH)
239
for (p = pLine + rBoundary.xLeft;
240
p <= pLine + rBoundary.xRight;
243
*p &= ~(PMC_DEBUG1 | PMC_DEBUG2);
249
static void CalculateDirectionsValues (BLOCK *pBlock)
251
LPOINT TopLeft, TopRight, BottomLeft, BottomRight;
256
// Get rectangle of block in real coordinates
258
TopLeft.x = pBlock -> Rect.xLeft;
259
TopLeft.y = pBlock -> Rect.yTop;
260
TopRight.x = pBlock -> Rect.xRight;
261
TopRight.y = pBlock -> Rect.yTop;
262
BottomLeft.x = pBlock -> Rect.xLeft;
263
BottomLeft.y = pBlock -> Rect.yBottom;
264
BottomRight.x = pBlock -> Rect.xRight;
265
BottomRight.y = pBlock -> Rect.yBottom;
267
REAL_XY (TopLeft.x , TopLeft.y);
268
REAL_XY (TopRight.x , TopRight.y);
269
REAL_XY (BottomLeft.x , BottomLeft.y);
270
REAL_XY (BottomRight.x, BottomRight.y);
272
rReal.xLeft = MIN (TopLeft.x, BottomLeft.x);
273
rReal.yTop = MIN (TopLeft.y, TopRight.y);
274
rReal.xRight = MAX (TopRight.x, BottomRight.x);
275
rReal.yBottom = MAX (BottomLeft.y, BottomRight.y);
277
// Normalize rectangle coordinates
279
rReal.xLeft = MIN (MAX (rReal.xLeft, 0), PAGE_MATRIX_REAL_WIDTH - 1);
280
rReal.yTop = MIN (MAX (rReal.yTop, 0), PAGE_MATRIX_REAL_HEIGHT - 1);
281
rReal.xRight = MIN (MAX (rReal.xRight, 0), PAGE_MATRIX_REAL_WIDTH - 1);
282
rReal.yBottom = MIN (MAX (rReal.yBottom, 0), PAGE_MATRIX_REAL_HEIGHT - 1);
284
// Calculate matrix coordinates
286
rMatrix.xLeft = XY_COMPRESS (rReal.xLeft);
287
rMatrix.xRight = XY_COMPRESS (rReal.xRight);
288
rMatrix.yTop = XY_COMPRESS (rReal.yTop);
289
rMatrix.yBottom = XY_COMPRESS (rReal.yBottom);
291
// Calculate directions values
293
for (i = 0; i < N_DIRECTIONS; i++)
296
Dirs [LEFT] .nWidth = rMatrix.yBottom - rMatrix.yTop + 1;
297
Dirs [TOP] .nWidth = rMatrix.xRight - rMatrix.xLeft + 1;
298
Dirs [RIGHT] .nWidth = rMatrix.yBottom - rMatrix.yTop + 1;
299
Dirs [BOTTOM].nWidth = rMatrix.xRight - rMatrix.xLeft + 1;
301
for (i = 0; i < N_DIRECTIONS; i++)
302
Dirs [i].nPictureSquare = 0;
304
for (nDistance = MIN_DISTANCE; nDistance <= MAX_DISTANCE; nDistance++)
306
Dirs [LEFT].nPictureSquare +=
307
PassVertInterval (rMatrix.xLeft - nDistance,
308
rMatrix.yTop, rMatrix.yBottom);
310
Dirs [TOP].nPictureSquare +=
311
PassHorzInterval (rMatrix.yTop - nDistance,
312
rMatrix.xLeft, rMatrix.xRight);
314
Dirs [RIGHT].nPictureSquare +=
315
PassVertInterval (rMatrix.xRight + nDistance,
316
rMatrix.yTop, rMatrix.yBottom);
318
Dirs [BOTTOM].nPictureSquare +=
319
PassHorzInterval (rMatrix.yBottom + nDistance,
320
rMatrix.xLeft, rMatrix.xRight);
323
q_sort ((char *) Dirs, N_DIRECTIONS, sizeof (DIRECTION), CompDirsPictureDensity); //AK 04.03.97
326
/****************************************************************************
330
* Blocks removing with dust distribution *
332
* Heuristic: If block contains many dust and this dust is *
333
* proportional distributed on block rectangle, this block *
334
* should be removed. *
336
***************************************************************************/
338
# define DD_MATRIX_WIDTH 2
339
# define DD_MATRIX_HEIGHT 2
340
# define DD_MATRIX_SIZE (DD_MATRIX_WIDTH * DD_MATRIX_HEIGHT)
342
int DQD_Matrix [DD_MATRIX_SIZE]; /* Dust Quantity Distribution */
343
int DSD_Matrix [DD_MATRIX_SIZE]; /* Dust Square Distribution */
345
static int DD_CompProc (const int *p, const int *q)
350
int CalculateSquareOfLetters (BLOCK *p)
355
for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext)
357
if (! IS_LAYOUT_DUST (*pRoot) &&
358
(pRoot -> bType & ROOT_LETTER) != 0)
360
nSquare += pRoot -> nWidth * pRoot -> nHeight;
367
void CalculateDustDistribution (BLOCK *p)
370
int nBlockWidth = p -> Rect.xRight - p -> Rect.xLeft + 1;
371
int nBlockHeight = p -> Rect.yBottom - p -> Rect.yTop + 1;
377
memset (DQD_Matrix, 0, DD_MATRIX_SIZE * sizeof (int));
378
memset (DSD_Matrix, 0, DD_MATRIX_SIZE * sizeof (int));
380
for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext)
383
if (! IS_LAYOUT_DUST (*pRoot))
387
x = (pRoot -> xColumn - p -> Rect.xLeft)
388
* DD_MATRIX_WIDTH / nBlockWidth;
390
y = (pRoot -> yRow - p -> Rect.yTop)
391
* DD_MATRIX_HEIGHT / nBlockHeight;
393
DQD_Matrix [x + y * DD_MATRIX_WIDTH]++;
395
DSD_Matrix [x + y * DD_MATRIX_WIDTH] +=
396
pRoot -> nWidth * pRoot -> nHeight;
402
for (i = 0; i < DD_MATRIX_SIZE; i++)
404
nDQD_Sum += DQD_Matrix [i];
405
nDSD_Sum += DSD_Matrix [i];
408
if (nDQD_Sum == 0 || nDSD_Sum == 0)
411
for (i = 0; i < DD_MATRIX_SIZE; i++)
413
DQD_Matrix [i] = DQD_Matrix [i] * 100 / nDQD_Sum;
414
DSD_Matrix [i] = DSD_Matrix [i] * 100 / nDSD_Sum;
417
q_sort ((char*)DQD_Matrix, DD_MATRIX_SIZE, sizeof (int), DD_CompProc); //AK 04.03.97
418
q_sort ((char*)DSD_Matrix, DD_MATRIX_SIZE, sizeof (int), DD_CompProc); //AK 04.03.97
422
static BOOL bAtLeastOneOutput;
425
void BlockRemove (BLOCK *p)
430
//if (LT_DebugGraphicsLevel == 2)
431
if(!LDPUMA_Skip(hRemoveEmptyBlocks))
434
LT_GraphicsBlockOutput2 ("Removed or converted blocks");
435
bAtLeastOneOutput = TRUE;
441
//DDD if(p -> Type == BLOCK_PICTURE){
442
//DDD int ret = del_picture( p -> hPicture);
447
for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext)
450
IS_LAYOUT_DUST (*pRoot) ? DUST_BLOCK_NUMBER : REMOVED_BLOCK_NUMBER;
453
BlocksRemoveDescriptor (p);
457
void BlockEnglish(BLOCK *p)
459
p -> language = LANG_ENGLISH;
462
void BlockConvertToDust (BLOCK *p)
467
//if (LT_DebugGraphicsLevel == 2)
468
if(!LDPUMA_Skip(hRemoveEmptyBlocks))
471
LT_GraphicsBlockOutput2 ("Removed or converted blocks");
472
bAtLeastOneOutput = TRUE;
476
for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext)
478
pRoot -> nBlock = DUST_BLOCK_NUMBER;
481
BlocksRemoveDescriptor (p);
484
void BlocksRemoveEmptyBlocks (void)
487
int nBlockWidth, nBlockHeight;
489
# ifdef LT_DEBUG_CALIBRATE
490
if (bDebugOptionCalibratePictureRemovingCriteria ||
491
bDebugOptionCalibrateDD_RemovingCriteria ||
492
bDebugOptionCalibrateLinearRemovingCriteria)
499
//if (LT_DebugGraphicsLevel == 2)
500
if(!LDPUMA_Skip(hRemoveEmptyBlocks))
502
LT_GraphicsClearScreen ();
503
bAtLeastOneOutput = FALSE;
509
while (pNext != NULL)
512
pNext = pNext -> pNext;
514
if (p -> Type != BLOCK_TEXT)
518
//if (LT_DebugGraphicsLevel >= 3)
519
if(!LDPUMA_Skip(hRemoveEmptyBlocks))
522
LT_ShowBlock("This block...");
527
nBlockWidth = p -> Rect.xRight - p -> Rect.xLeft + 1;
528
nBlockHeight = p -> Rect.yBottom - p -> Rect.yTop + 1;
530
if (p -> nRoots == p -> nDust)
536
if (! bOptionBlocksRemovingByPageMatrix)
537
goto AFTER_REMOVING_BY_PAGE_MATRIX;
539
if (p -> nLetters > 5 ||
540
p -> nRoots - p -> nDust > 50)
542
goto AFTER_REMOVING_BY_PAGE_MATRIX;
545
CalculateDirectionsValues (p);
547
if (Dirs [0].nPictureSquare >= Dirs [0].nWidth &&
548
Dirs [1].nPictureSquare >= Dirs [1].nWidth &&
549
Dirs [2].nPictureSquare >= Dirs [2].nWidth / 2
551
Dirs [0].nPictureSquare >= Dirs [0].nWidth * 2 &&
552
Dirs [1].nPictureSquare >= Dirs [1].nWidth * 2 &&
553
Dirs [2].nPictureSquare >= Dirs [2].nWidth / 3)
556
//if (LT_DebugGraphicsLevel >= 3)
557
if(!LDPUMA_Skip(hRemoveEmptyBlocks))
559
CalculateDirectionsValues (p);
561
PrepareDebugPictureOutput ();
563
rDebugRect = rBoundary;
565
LT_GraphicsPictureRemovingConditionsOutput2
566
("Remove by PageMatrix");
568
UnPrepareDebugPictureOutput ();
576
AFTER_REMOVING_BY_PAGE_MATRIX:
579
# ifdef LT_DEBUG_CALIBRATE
580
if (bDebugOptionCalibratePictureRemovingCriteria &&
586
CalculateDirectionsValues (p);
588
PrepareDebugPictureOutput ();
590
rDebugRect = rBoundary;
592
LT_GraphicsPictureRemovingConditionsOutput2
593
("Picture removing conditions");
595
UnPrepareDebugPictureOutput ();
597
cAnswer = LT_Getch ();
601
printf ("Roots: %4d Letters: %4d NoDust: %4d Dust: %4d ",
604
p -> nRoots - p -> nDust,
607
printf ("Width %4d Height: %4d [ ", nBlockWidth, nBlockHeight);
609
for (i = 0; i < N_DIRECTIONS; i++)
612
(double) Dirs [i].nPictureSquare / Dirs [i].nWidth);
622
if (! bOptionBlocksRemovingByDustDistribution)
623
goto AFTER_REMOVING_BY_DUST_DISTRIBUTION;
625
if (p -> nDust < 3 * (p -> nRoots - p -> nDust) ||
626
CalculateSquareOfLetters (p)
627
> (p -> Rect.xRight - p -> Rect.xLeft + 1) *
628
(p -> Rect.yBottom - p -> Rect.yTop + 1) / 3)
630
goto AFTER_REMOVING_BY_DUST_DISTRIBUTION;
633
CalculateDustDistribution (p);
635
if (DSD_Matrix [0] <= 75 && DQD_Matrix [0] <= 60 &&
636
// DSD_Matrix [2] >= 7 && DQD_Matrix [2] >= 11
637
DSD_Matrix [3] >= 7 && DQD_Matrix [3] >= 11 // Pit 7-7-94
638
&& CalculateSquareOfLetters (p) == 0 // Pit
642
//if (LT_DebugGraphicsLevel >= 3)
643
if(!LDPUMA_Skip(hRemoveEmptyBlocks))
645
CalculateDustDistribution (p);
648
rDebugRect.xLeft = 0;
649
rDebugRect.xRight = DD_MATRIX_WIDTH - 1;
651
rDebugRect.yBottom = DD_MATRIX_HEIGHT - 1;
653
LT_GraphicsDD_RemovingConditionsOutput2
654
("Remove by dust distribution");
663
AFTER_REMOVING_BY_DUST_DISTRIBUTION:
666
# ifdef LT_DEBUG_CALIBRATE
667
if (bDebugOptionCalibrateDD_RemovingCriteria)
672
CalculateDustDistribution (p);
675
rDebugRect.xLeft = 0;
676
rDebugRect.xRight = DD_MATRIX_WIDTH - 1;
678
rDebugRect.yBottom = DD_MATRIX_HEIGHT - 1;
680
LT_GraphicsDD_RemovingConditionsOutput2 ("Dust distribution");
682
cAnswer = LT_Getch ();
686
printf ("Roots: %4d Letters: %4d NoDust: %4d Dust: %4d ",
689
p -> nRoots - p -> nDust,
692
printf ("Width %4d Height: %4d [ ", nBlockWidth, nBlockHeight);
694
for (i = 0; i < DD_MATRIX_SIZE; i++)
696
printf ("%5.2f ", (double) DSD_Matrix [i] / DQD_Matrix [i]);
707
p -> nLetters == 0 &&
708
p -> nRoots - p -> nDust <= 10 && /* CRSH5 */
710
nBlockWidth <= MAX_DUST_WIDTH / 2 &&
711
nBlockHeight / nBlockWidth >= 7
713
p -> nLetters == 0 &&
714
p -> nRoots - p -> nDust <= 2 &&
716
nBlockHeight <= MAX_DUST_HEIGHT &&
717
nBlockWidth / nBlockHeight >= 10
719
p -> nLetters == 0 &&
720
p -> nRoots - p -> nDust == 1 &&
721
nBlockHeight < MAX_DUST_HEIGHT * 3 / 2
723
p -> nLetters == 0 &&
724
p -> nRoots - p -> nDust < 5 &&
725
nBlockHeight < MAX_DUST_HEIGHT * 4 &&
726
nBlockWidth < MAX_DUST_WIDTH * 4)
730
! ( /* Page number */
732
p -> Rect.xLeft > rRootSpace.xLeft + nRootSpaceWidth * 3 / 10 &&
733
p -> Rect.xRight < rRootSpace.xLeft + nRootSpaceWidth * 7 / 10 &&
734
p -> Rect.yTop > rRootSpace.yTop + nRootSpaceHeight * 7 / 10 &&
735
nBlockHeight > MAX_DUST_HEIGHT &&
736
nBlockWidth > MAX_DUST_WIDTH
740
//if (LT_DebugGraphicsLevel >= 3)
741
if(!LDPUMA_Skip(hRemoveEmptyBlocks))
745
LT_GraphicsLinearRemovingConditionsOutput2
746
("Converted to dust by block parameter heuristic");
751
BlockConvertToDust (p);
755
# ifdef LT_DEBUG_CALIBRATE
756
if (bDebugOptionCalibrateLinearRemovingCriteria &&
762
LT_GraphicsLinearRemovingConditionsOutput2 ("Remove");
763
cAnswer = LT_Getch ();
767
printf ("Roots: %4d Letters: %4d NoDust: %4d Dust: %4d ",
770
p -> nRoots - p -> nDust,
773
printf ("Width %4d Height: %4d H/W: %5.2f\n",
776
p -> Rect.xRight - p -> Rect.xLeft + 1,
777
p -> Rect.yBottom - p -> Rect.yTop + 1,
778
(double) (p -> Rect.yBottom - p -> Rect.yTop + 1) /
779
(p -> Rect.xRight - p -> Rect.xLeft + 1)
788
if (p -> nLetters <= (p -> nRoots - p -> nDust) / 10)
797
//if (LT_DebugGraphicsLevel == 2 && bAtLeastOneOutput)
798
if (!LDPUMA_Skip(hRemoveEmptyBlocks) && bAtLeastOneOutput)
802
# ifdef LT_DEBUG_CALIBRATE
803
if (bDebugOptionCalibratePictureRemovingCriteria ||
804
bDebugOptionCalibrateDD_RemovingCriteria ||
805
bDebugOptionCalibrateLinearRemovingCriteria)
808
ErrorInternal ("Calibrating complete");