code_128b_view.cpp
2.92 KB
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
#include "code_128b_view.h"
namespace HardwareTest {
constexpr uint16_t patterns[] = {0x6CC, 0x66C, 0x666, 0x498, 0x48C, 0x44C, 0x4C8, 0x4C4, 0x464, 0x648, 0x644, 0x624, 0x59C, 0x4DC, 0x4CE, 0x5CC, 0x4EC, 0x4E6, 0x672, 0x65C, 0x64E, 0x6E4, 0x674, 0x76E, 0x74C, 0x72C, 0x726, 0x764, 0x734, 0x732, 0x6D8, 0x6C6, 0x636, 0x518, 0x458, 0x446, 0x588, 0x468, 0x462, 0x688, 0x628, 0x622, 0x5B8, 0x58E, 0x46E, 0x5D8, 0x5C6, 0x476, 0x776, 0x68E, 0x62E, 0x6E8, 0x6E2, 0x6EE, 0x758, 0x746, 0x716, 0x768, 0x762, 0x71A, 0x77A, 0x642, 0x78A, 0x530, 0x50C, 0x4B0, 0x486, 0x42C, 0x426, 0x590, 0x584, 0x4D0, 0x4C2, 0x434, 0x432, 0x612, 0x650, 0x7BA, 0x614, 0x47A, 0x53C, 0x4BC, 0x49E, 0x5E4, 0x4F4, 0x4F2, 0x7A4, 0x794, 0x792, 0x6DE, 0x6F6, 0x7B6, 0x578, 0x51E, 0x45E, 0x5E8, 0x5E2, 0x7A8, 0x7A2, 0x5DE, 0x5EE, 0x75E, 0x7AE};
constexpr uint16_t startPattern = 0x690;
constexpr uint16_t stopPattern = 0x18EB;
Code128BView::Code128BView() :
View(),
m_moduleWidth(0),
m_data(nullptr)
{
}
void Code128BView::setData(const char * data) {
m_data = data;
markRectAsDirty(bounds());
}
void Code128BView::layoutSubviews() {
updateModuleWidth();
}
void Code128BView::updateModuleWidth() {
if (m_data == nullptr) {
m_moduleWidth = 0;
return;
}
int numberOfModules =
10 + // quiet zone
11 + // start
11 * strlen(m_data) + // data
11 + // checksum
13; // stop
m_moduleWidth = bounds().width() / numberOfModules;
}
void Code128BView::drawQuietZoneAt(KDContext * ctx, KDCoordinate * x) const {
ctx->fillRect(KDRect(*x, 0, 10*m_moduleWidth, bounds().height()), KDColorWhite);
*x = *x + 10*m_moduleWidth;
}
void Code128BView::drawPatternAt(KDContext * ctx, uint16_t pattern, KDCoordinate * x, KDCoordinate width) const {
assert(width <= 16);
for (int i=0; i<width; i++) {
if (pattern & (1<<(width-i-1))) {
ctx->fillRect(KDRect(*x, 0, m_moduleWidth, bounds().height()), KDColorBlack);
}
*x = *x + m_moduleWidth;
}
}
void Code128BView::drawCharAt(KDContext * ctx, char c, KDCoordinate * x) const {
return drawPatternAt(ctx, patterns[c-32], x);
}
int Code128BView::checksum() const {
int checksum = 104;
const char * letter = m_data;
int i = 1;
while (*letter != 0) {
checksum += (*letter - 32)*i;
i++;
letter++;
}
return checksum % 103;
}
// Serial Number is 96 bits = 4 * 24 bits = 4 * 4 letters in Base64 = 16 letters
void Code128BView::drawRect(KDContext * ctx, KDRect rect) const {
if (m_moduleWidth == 0) {
// Not enough space for given string
ctx->fillRect(rect, KDColorRed);
return;
}
ctx->fillRect(rect, KDColorWhite);
KDCoordinate x = 0;
drawQuietZoneAt(ctx, &x);
drawPatternAt(ctx, startPattern, &x);
const char * letter = m_data;
while (*letter != 0) {
drawCharAt(ctx, *letter, &x);
letter++;
}
drawPatternAt(ctx, patterns[checksum()], &x);
drawPatternAt(ctx, stopPattern, &x, 13);
drawQuietZoneAt(ctx, &x);
ctx->drawString(m_data, KDPointZero);
}
}