-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcarve.cpp
146 lines (126 loc) · 3.51 KB
/
carve.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "stdafx.h"
int
carve(DOTMATRIX* dm, FontSize* size, Font* fonts, size_t* found)
{
DotMatrixPot pot = { 0, 0 }, prev = pot, *start = &pot;
DotMatrixRange *range;
DotMatrixRange **ranges;
size_t n_range = 100, c_range = 0;
if((ranges = (DotMatrixRange**)malloc(sizeof(DotMatrixRange*)*n_range)) == NULL) return 3;
do {
prev = *start;
carveRange(dm, start, size, range);
if (n_range == c_range) { printf("The number of blocks of range has reached maximum\n"); return 4; }
ranges[c_range++] = range;
} while(dmpCmp(&prev, start));
for (size_t i = 0; i < c_range; ++i) {
carveFont(dm, ranges[i], fonts, size, found);
free(ranges[i]);
}
free(ranges);
return 0;
}
static int
dmpCmp(DotMatrixPot* p1, DotMatrixPot* p2) {
return (p1->r != p2->r) || (p2->c != p2->c);
}
static size_t
width(DotMatrixRange* range)
{
size_t w = range->cpr.c - range->cpl.c;
if(w < 0) w = 0;
return w;
}
static size_t
count(DotMatrixRange* range, FontSize *size)
{
size_t c = width(range) / size->w;
return c;
}
static int
carveRange(DOTMATRIX* dm, DotMatrixPot* start, FontSize *size, DotMatrixRange* range)
{
if((range = (DotMatrixRange*)malloc(sizeof(DotMatrixRange))) == NULL) return 3;
dmpScanLH(dm, start);
range->cpl = dmpScanLV(dm, start, size);
range->cpr = dmpScanRV(dm, start, size);
return 0;
}
static int
carveFont(DOTMATRIX *dm, DotMatrixRange* range, Font* fonts, FontSize *size, size_t* found)
{
Font* font;
DotMatrixPot pot;
DOTMATRIX* dots;
size_t n = count(range, size), c, i, j;
if(n <= 0) return 2;
if((fonts = (Font*)malloc(sizeof(Font)*n)) == NULL) return 3;
pot.c = range->cpl.c;
pot.r = range->cpr.r;
*found = 0;
for(c = 0; pot.c < range->cpr.c; ++c, pot.c += size->w) {
font = &fonts[c];
if(DotMatrix(&pot, &(range->cpr), dm, dots) != 0) return 4;
font = dots;
++(*found);
}
return 0;
}
static int
DotMatrix(DotMatrixPot* corner, DotMatrixPot* bottom, const DOTMATRIX* dm, DOTMATRIX* odm)
{
odm->r = bottom->r - corner->r;
odm->c = bottom->c - corner->c;
size_t* rows;
size_t i, j = 0, m = 0, n, stop = corner->r + odm->r;
if ((odm->map = (size_t**)malloc(sizeof(size_t*)* odm->r)) == NULL) return 3;
for (i = corner->r, n = 0; i < stop; ++i, n = 0) {
if ((rows = (size_t*)malloc(sizeof(size_t)* odm->c)) == NULL) return 3;
for (j = corner->c; j < bottom->c; ++j) rows[n++] = dm->map[i][j];
odm->map[m++] = rows;
}
return 0;
}
static void
dmpScanLH(DOTMATRIX *dm, DotMatrixPot* start) // scan dot matrix to left by horizontal
{
for (; start->r < dm->r; ++start->r) {
for (; start->c < dm->c; ++start->c) { if (dm->map[start->r][start->c] == 1) return; }
start->c = 0;
}
}
static DotMatrixPot
dmpScanLV(DOTMATRIX *dm, DotMatrixPot* start, const FontSize* size)
{
DotMatrixPot pot;
size_t i, j = start->c, stop = size->h + start->r;
if (dm->r < stop || dm->c == start->c) return ;
for (i = start->r; start->r < stop; ++i) {
if (j == 0) break;
if (dm->map[i][j] == 1) { --j; i = start->r; }
}
start->c = ++j;
pot.r = start->r;
pot.c = start->c;
return pot;
}
static DotMatrixPot
dmpScanRV(DOTMATRIX *dm, const DotMatrixPot* start, const FontSize* size)
{
DotMatrixPot pot;
size_t limit = 0;
pot.c = pot.r = 0;
size_t i, j = start->c, stop = size->h + start->r;
if (dm->r < stop || dm->c == start->c) return pot;
do {
for (i = start->r; i < stop; ++i) {
if (j == dm->c - 1) goto ENDMAT;
if (dm->map[i][j] == 1) { ++j; i = start->r; }
}
++limit; ++j; i = start->r;
} while (limit < 3);
ENDMAT:
pot.r = start->r + size->h;
pot.c = j - limit;
return pot;
}