181 |
ilm |
1 |
/*
|
|
|
2 |
* Copyright 2014 Robin Stuart
|
|
|
3 |
*
|
|
|
4 |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
|
5 |
* in compliance with the License. You may obtain a copy of the License at
|
|
|
6 |
*
|
|
|
7 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
8 |
*
|
|
|
9 |
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
|
10 |
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
|
11 |
* or implied. See the License for the specific language governing permissions and limitations under
|
|
|
12 |
* the License.
|
|
|
13 |
*/
|
|
|
14 |
package uk.org.okapibarcode.backend;
|
|
|
15 |
|
|
|
16 |
import static uk.org.okapibarcode.util.Arrays.positionOf;
|
|
|
17 |
|
|
|
18 |
import java.awt.geom.Rectangle2D;
|
|
|
19 |
import java.util.Locale;
|
|
|
20 |
|
|
|
21 |
/**
|
|
|
22 |
* <p>
|
|
|
23 |
* Encodes data according to the Royal Mail 4-State Country Code.
|
|
|
24 |
*
|
|
|
25 |
* <p>
|
|
|
26 |
* Data input can consist of numbers 0-9 and letters A-Z and usually includes delivery postcode
|
|
|
27 |
* followed by house number. A check digit is calculated and added.
|
|
|
28 |
*
|
|
|
29 |
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
|
|
|
30 |
*/
|
|
|
31 |
public class RoyalMail4State extends Symbol {
|
|
|
32 |
|
|
|
33 |
private static final String[] ROYAL_TABLE = { "TTFF", "TDAF", "TDFA", "DTAF", "DTFA", "DDAA", "TADF", "TFTF", "TFDA", "DATF", "DADA", "DFTA", "TAFD", "TFAD", "TFFT", "DAAD", "DAFT", "DFAT",
|
|
|
34 |
"ATDF", "ADTF", "ADDA", "FTTF", "FTDA", "FDTA", "ATFD", "ADAD", "ADFT", "FTAD", "FTFT", "FDAT", "AADD", "AFTD", "AFDT", "FATD", "FADT", "FFTT" };
|
|
|
35 |
|
|
|
36 |
private static final char[] KR_SET = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
|
|
|
37 |
'V', 'W', 'X', 'Y', 'Z' };
|
|
|
38 |
|
|
|
39 |
@Override
|
|
|
40 |
protected void encode() {
|
|
|
41 |
String dest;
|
|
|
42 |
int i, top = 0, bottom = 0;
|
|
|
43 |
int row, column;
|
|
|
44 |
int index;
|
|
|
45 |
|
|
|
46 |
this.content = this.content.toUpperCase(Locale.ENGLISH);
|
|
|
47 |
if (!this.content.matches("[0-9A-Z]+")) {
|
|
|
48 |
throw new OkapiException("Invalid characters in data");
|
|
|
49 |
}
|
|
|
50 |
dest = "A";
|
|
|
51 |
|
|
|
52 |
for (i = 0; i < this.content.length(); i++) {
|
|
|
53 |
index = positionOf(this.content.charAt(i), KR_SET);
|
|
|
54 |
dest += ROYAL_TABLE[index];
|
|
|
55 |
top += (index + 1) % 6;
|
|
|
56 |
bottom += (index / 6 + 1) % 6;
|
|
|
57 |
}
|
|
|
58 |
|
|
|
59 |
/* calculate check digit */
|
|
|
60 |
row = top % 6 - 1;
|
|
|
61 |
column = bottom % 6 - 1;
|
|
|
62 |
if (row == -1) {
|
|
|
63 |
row = 5;
|
|
|
64 |
}
|
|
|
65 |
if (column == -1) {
|
|
|
66 |
column = 5;
|
|
|
67 |
}
|
|
|
68 |
final int check = 6 * row + column;
|
|
|
69 |
dest += ROYAL_TABLE[check];
|
|
|
70 |
infoLine("Check Digit: " + check);
|
|
|
71 |
|
|
|
72 |
/* Stop character */
|
|
|
73 |
dest += "F";
|
|
|
74 |
|
|
|
75 |
infoLine("Encoding: " + dest);
|
|
|
76 |
this.readable = "";
|
|
|
77 |
this.pattern = new String[1];
|
|
|
78 |
this.pattern[0] = dest;
|
|
|
79 |
this.row_count = 1;
|
|
|
80 |
this.row_height = new int[1];
|
|
|
81 |
this.row_height[0] = -1;
|
|
|
82 |
}
|
|
|
83 |
|
|
|
84 |
@Override
|
|
|
85 |
protected void plotSymbol() {
|
|
|
86 |
int xBlock;
|
|
|
87 |
int x, y, w, h;
|
|
|
88 |
|
|
|
89 |
this.rectangles.clear();
|
|
|
90 |
x = 0;
|
|
|
91 |
w = 1;
|
|
|
92 |
y = 0;
|
|
|
93 |
h = 0;
|
|
|
94 |
for (xBlock = 0; xBlock < this.pattern[0].length(); xBlock++) {
|
|
|
95 |
switch (this.pattern[0].charAt(xBlock)) {
|
|
|
96 |
case 'A':
|
|
|
97 |
y = 0;
|
|
|
98 |
h = 5;
|
|
|
99 |
break;
|
|
|
100 |
case 'D':
|
|
|
101 |
y = 3;
|
|
|
102 |
h = 5;
|
|
|
103 |
break;
|
|
|
104 |
case 'F':
|
|
|
105 |
y = 0;
|
|
|
106 |
h = 8;
|
|
|
107 |
break;
|
|
|
108 |
case 'T':
|
|
|
109 |
y = 3;
|
|
|
110 |
h = 2;
|
|
|
111 |
break;
|
|
|
112 |
}
|
|
|
113 |
|
|
|
114 |
final Rectangle2D.Double rect = new Rectangle2D.Double(x, y, w, h);
|
|
|
115 |
this.rectangles.add(rect);
|
|
|
116 |
|
|
|
117 |
x += 2;
|
|
|
118 |
}
|
|
|
119 |
this.symbol_width = this.pattern[0].length() * 3;
|
|
|
120 |
this.symbol_height = 8;
|
|
|
121 |
}
|
|
|
122 |
}
|