Blame view

build4/epsilon-master/apps/hardware_test/code_128b_view.cpp 2.92 KB
6663b6c9   adorian   projet complet av...
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
  #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);
  }
  
  }