1 package datamatrix
2
3 import (
4 "github.com/boombuler/barcode/utils"
5 "strconv"
6 )
7
8 type setValFunc func(byte)
9
10 type codeLayout struct {
11 matrix *utils.BitList
12 occupy *utils.BitList
13 size *dmCodeSize
14 }
15
16 func newCodeLayout(size *dmCodeSize) *codeLayout {
17 result := new(codeLayout)
18 result.matrix = utils.NewBitList(size.MatrixColumns() * size.MatrixRows())
19 result.occupy = utils.NewBitList(size.MatrixColumns() * size.MatrixRows())
20 result.size = size
21 return result
22 }
23
24 func (l *codeLayout) Occupied(row, col int) bool {
25 return l.occupy.GetBit(col + row*l.size.MatrixColumns())
26 }
27
28 func (l *codeLayout) Set(row, col int, value, bitNum byte) {
29 val := ((value >> (7 - bitNum)) & 1) == 1
30 if row < 0 {
31 row += l.size.MatrixRows()
32 col += 4 - ((l.size.MatrixRows() + 4) % 8)
33 }
34 if col < 0 {
35 col += l.size.MatrixColumns()
36 row += 4 - ((l.size.MatrixColumns() + 4) % 8)
37 }
38 if l.Occupied(row, col) {
39 panic("Field already occupied row: " + strconv.Itoa(row) + " col: " + strconv.Itoa(col))
40 }
41
42 l.occupy.SetBit(col+row*l.size.MatrixColumns(), true)
43
44 l.matrix.SetBit(col+row*l.size.MatrixColumns(), val)
45 }
46
47 func (l *codeLayout) SetSimple(row, col int, value byte) {
48 l.Set(row-2, col-2, value, 0)
49 l.Set(row-2, col-1, value, 1)
50 l.Set(row-1, col-2, value, 2)
51 l.Set(row-1, col-1, value, 3)
52 l.Set(row-1, col-0, value, 4)
53 l.Set(row-0, col-2, value, 5)
54 l.Set(row-0, col-1, value, 6)
55 l.Set(row-0, col-0, value, 7)
56 }
57
58 func (l *codeLayout) Corner1(value byte) {
59 l.Set(l.size.MatrixRows()-1, 0, value, 0)
60 l.Set(l.size.MatrixRows()-1, 1, value, 1)
61 l.Set(l.size.MatrixRows()-1, 2, value, 2)
62 l.Set(0, l.size.MatrixColumns()-2, value, 3)
63 l.Set(0, l.size.MatrixColumns()-1, value, 4)
64 l.Set(1, l.size.MatrixColumns()-1, value, 5)
65 l.Set(2, l.size.MatrixColumns()-1, value, 6)
66 l.Set(3, l.size.MatrixColumns()-1, value, 7)
67 }
68
69 func (l *codeLayout) Corner2(value byte) {
70 l.Set(l.size.MatrixRows()-3, 0, value, 0)
71 l.Set(l.size.MatrixRows()-2, 0, value, 1)
72 l.Set(l.size.MatrixRows()-1, 0, value, 2)
73 l.Set(0, l.size.MatrixColumns()-4, value, 3)
74 l.Set(0, l.size.MatrixColumns()-3, value, 4)
75 l.Set(0, l.size.MatrixColumns()-2, value, 5)
76 l.Set(0, l.size.MatrixColumns()-1, value, 6)
77 l.Set(1, l.size.MatrixColumns()-1, value, 7)
78 }
79
80 func (l *codeLayout) Corner3(value byte) {
81 l.Set(l.size.MatrixRows()-3, 0, value, 0)
82 l.Set(l.size.MatrixRows()-2, 0, value, 1)
83 l.Set(l.size.MatrixRows()-1, 0, value, 2)
84 l.Set(0, l.size.MatrixColumns()-2, value, 3)
85 l.Set(0, l.size.MatrixColumns()-1, value, 4)
86 l.Set(1, l.size.MatrixColumns()-1, value, 5)
87 l.Set(2, l.size.MatrixColumns()-1, value, 6)
88 l.Set(3, l.size.MatrixColumns()-1, value, 7)
89 }
90
91 func (l *codeLayout) Corner4(value byte) {
92 l.Set(l.size.MatrixRows()-1, 0, value, 0)
93 l.Set(l.size.MatrixRows()-1, l.size.MatrixColumns()-1, value, 1)
94 l.Set(0, l.size.MatrixColumns()-3, value, 2)
95 l.Set(0, l.size.MatrixColumns()-2, value, 3)
96 l.Set(0, l.size.MatrixColumns()-1, value, 4)
97 l.Set(1, l.size.MatrixColumns()-3, value, 5)
98 l.Set(1, l.size.MatrixColumns()-2, value, 6)
99 l.Set(1, l.size.MatrixColumns()-1, value, 7)
100 }
101
102 func (l *codeLayout) SetValues(data []byte) {
103 idx := 0
104 row := 4
105 col := 0
106
107 for (row < l.size.MatrixRows()) || (col < l.size.MatrixColumns()) {
108 if (row == l.size.MatrixRows()) && (col == 0) {
109 l.Corner1(data[idx])
110 idx++
111 }
112 if (row == l.size.MatrixRows()-2) && (col == 0) && (l.size.MatrixColumns()%4 != 0) {
113 l.Corner2(data[idx])
114 idx++
115 }
116 if (row == l.size.MatrixRows()-2) && (col == 0) && (l.size.MatrixColumns()%8 == 4) {
117 l.Corner3(data[idx])
118 idx++
119 }
120
121 if (row == l.size.MatrixRows()+4) && (col == 2) && (l.size.MatrixColumns()%8 == 0) {
122 l.Corner4(data[idx])
123 idx++
124 }
125
126 for true {
127 if (row < l.size.MatrixRows()) && (col >= 0) && !l.Occupied(row, col) {
128 l.SetSimple(row, col, data[idx])
129 idx++
130 }
131 row -= 2
132 col += 2
133 if (row < 0) || (col >= l.size.MatrixColumns()) {
134 break
135 }
136 }
137 row += 1
138 col += 3
139
140 for true {
141 if (row >= 0) && (col < l.size.MatrixColumns()) && !l.Occupied(row, col) {
142 l.SetSimple(row, col, data[idx])
143 idx++
144 }
145 row += 2
146 col -= 2
147 if (row >= l.size.MatrixRows()) || (col < 0) {
148 break
149 }
150 }
151 row += 3
152 col += 1
153 }
154
155 if !l.Occupied(l.size.MatrixRows()-1, l.size.MatrixColumns()-1) {
156 l.Set(l.size.MatrixRows()-1, l.size.MatrixColumns()-1, 255, 0)
157 l.Set(l.size.MatrixRows()-2, l.size.MatrixColumns()-2, 255, 0)
158 }
159 }
160
161 func (l *codeLayout) Merge() *datamatrixCode {
162 result := newDataMatrixCode(l.size)
163
164
165 for r := 0; r < l.size.Rows; r += (l.size.RegionRows() + 2) {
166 for c := 0; c < l.size.Columns; c += 2 {
167 result.set(c, r, true)
168 }
169 }
170
171
172 for r := l.size.RegionRows() + 1; r < l.size.Rows; r += (l.size.RegionRows() + 2) {
173 for c := 0; c < l.size.Columns; c++ {
174 result.set(c, r, true)
175 }
176 }
177
178
179 for c := l.size.RegionColumns() + 1; c < l.size.Columns; c += (l.size.RegionColumns() + 2) {
180 for r := 1; r < l.size.Rows; r += 2 {
181 result.set(c, r, true)
182 }
183 }
184
185
186 for c := 0; c < l.size.Columns; c += (l.size.RegionColumns() + 2) {
187 for r := 0; r < l.size.Rows; r++ {
188 result.set(c, r, true)
189 }
190 }
191 count := 0
192 for hRegion := 0; hRegion < l.size.RegionCountHorizontal; hRegion++ {
193 for vRegion := 0; vRegion < l.size.RegionCountVertical; vRegion++ {
194 for x := 0; x < l.size.RegionColumns(); x++ {
195 colMatrix := (l.size.RegionColumns() * hRegion) + x
196 colResult := ((2 + l.size.RegionColumns()) * hRegion) + x + 1
197
198 for y := 0; y < l.size.RegionRows(); y++ {
199 rowMatrix := (l.size.RegionRows() * vRegion) + y
200 rowResult := ((2 + l.size.RegionRows()) * vRegion) + y + 1
201 val := l.matrix.GetBit(colMatrix + rowMatrix*l.size.MatrixColumns())
202 if val {
203 count++
204 }
205
206 result.set(colResult, rowResult, val)
207 }
208 }
209 }
210 }
211
212 return result
213 }
214
View as plain text