mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Code39 extended mode encoding support (#876)
* asterisk isn't a valid character which can be encoded with Code 39. the following sample content results in an unreadable barcode: *123456789 because the asterisk is the start-stop character (special meaning, not valid in content) the really encoded value is **123456789*. The barcode reader stops after reading the second asterisk and throw the content away. * remove wrong private modifier for ALPHABET_STRING * cleanup comments * add support for Code 39 extended mode encoding * add support for Code 39 extended mode encoding * clean ups * clean ups
This commit is contained in:
parent
76d9dd5cf6
commit
437db89b45
|
@ -50,13 +50,23 @@ public final class Code39Writer extends OneDimensionalCodeWriter {
|
|||
"Requested contents should be less than 80 digits long, but got " + length);
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int indexInString = Code39Reader.ALPHABET_STRING.indexOf(contents.charAt(i));
|
||||
if (indexInString < 0) {
|
||||
contents = tryToConvertToExtendedMode(contents);
|
||||
length = contents.length();
|
||||
if (length > 80) {
|
||||
throw new IllegalArgumentException(
|
||||
"Requested contents should be less than 80 digits long, but got " + length + " (extended full ASCII mode)");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int[] widths = new int[9];
|
||||
int codeWidth = 24 + 1 + length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
int indexInString = Code39Reader.ALPHABET_STRING.indexOf(contents.charAt(i));
|
||||
if (indexInString < 0) {
|
||||
throw new IllegalArgumentException("Bad contents: " + contents);
|
||||
}
|
||||
toIntArray(Code39Reader.CHARACTER_ENCODINGS[indexInString], widths);
|
||||
for (int width : widths) {
|
||||
codeWidth += width;
|
||||
|
@ -86,4 +96,60 @@ public final class Code39Writer extends OneDimensionalCodeWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private static String tryToConvertToExtendedMode(String contents) {
|
||||
int length = contents.length();
|
||||
StringBuilder extendedContent = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
char character = contents.charAt(i);
|
||||
switch (character) {
|
||||
case '\u0000':
|
||||
extendedContent.append("%U");
|
||||
break;
|
||||
case ' ':
|
||||
case '-':
|
||||
case '.':
|
||||
extendedContent.append(character);
|
||||
break;
|
||||
case '@':
|
||||
extendedContent.append("%V");
|
||||
break;
|
||||
case '`':
|
||||
extendedContent.append("%W");
|
||||
break;
|
||||
default:
|
||||
if (character > 0 && character < 27) {
|
||||
extendedContent.append('$');
|
||||
extendedContent.append((char) ('A' + (character - 1)));
|
||||
} else if (character > 26 && character < ' ') {
|
||||
extendedContent.append('%');
|
||||
extendedContent.append((char) ('A' + (character - 27)));
|
||||
} else if ((character > ' ' && character < '-') || character == '/' || character == ':') {
|
||||
extendedContent.append('/');
|
||||
extendedContent.append((char) ('A' + (character - 33)));
|
||||
} else if (character > '/' && character < ':') {
|
||||
extendedContent.append((char) ('0' + (character - 48)));
|
||||
} else if (character > ':' && character < '@') {
|
||||
extendedContent.append('%');
|
||||
extendedContent.append((char) ('F' + (character - 59)));
|
||||
} else if (character > '@' && character < '[') {
|
||||
extendedContent.append((char) ('A' + (character - 65)));
|
||||
} else if (character > 'Z' && character < '`') {
|
||||
extendedContent.append('%');
|
||||
extendedContent.append((char) ('K' + (character - 91)));
|
||||
} else if (character > '`' && character < '{') {
|
||||
extendedContent.append('+');
|
||||
extendedContent.append((char) ('A' + (character - 97)));
|
||||
} else if (character > 'z' && character < 128) {
|
||||
extendedContent.append('%');
|
||||
extendedContent.append((char) ('P' + (character - 123)));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Requested content contains a non-encodable character: '" + contents.charAt(i) + "'");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return extendedContent.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,11 +34,58 @@ public final class Code39WriterTestCase extends Assert {
|
|||
"101101011001010101101100101100101010110100110101011011001101010101001011010110110010" +
|
||||
"110101010011011010101010011011010110100101011010110010101101101100101010101001101011" +
|
||||
"01101001101010101100110101010100101101101101001011010101100101101010010110110100000");
|
||||
|
||||
// extended mode blocks
|
||||
doTest("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f",
|
||||
"000001001011011010101001001001011001010101101001001001010110101001011010010010010101" +
|
||||
"011010010110100100100101011011010010101001001001010101011001011010010010010101101011" +
|
||||
"001010100100100101010110110010101001001001010101010011011010010010010101101010011010" +
|
||||
"100100100101010110100110101001001001010101011001101010010010010101101010100110100100" +
|
||||
"100101010110101001101001001001010110110101001010010010010101010110100110100100100101" +
|
||||
"011010110100101001001001010101101101001010010010010101010101100110100100100101011010" +
|
||||
"101100101001001001010101101011001010010010010101010110110010100100100101011001010101" +
|
||||
"101001001001010100110101011010010010010101100110101010100100100101010010110101101001" +
|
||||
"001001010110010110101010010010010101001101101010101001001001011010100101101010010010" +
|
||||
"010101101001011010100100100101101101001010101001001001010101100101101010010010010110" +
|
||||
"101100101010010110110100000");
|
||||
|
||||
doTest(" !\"#$%&'()*+,-./0123456789:;<=>?",
|
||||
"000001001011011010100110101101010010010100101101010010110100100101001010110100101101" +
|
||||
"001001010010110110100101010010010100101010110010110100100101001011010110010101001001" +
|
||||
"010010101101100101010010010100101010100110110100100101001011010100110101001001010010" +
|
||||
"101101001101010010010100101010110011010100100101001011010101001101001001010010101101" +
|
||||
"010011010010101101101100101011010100100101001011010110100101010011011010110100101011" +
|
||||
"010110010101101101100101010101001101011011010011010101011001101010101001011011011010" +
|
||||
"010110101011001011010100100101001010011011010101010010010010101101100101010100100100" +
|
||||
"101010100110110101001001001011010100110101010010010010101101001101010100100100101010" +
|
||||
"11001101010010110110100000");
|
||||
|
||||
doTest("@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_",
|
||||
"0000010010110110101010010010010100110101011011010100101101011010010110110110100101010" +
|
||||
"101100101101101011001010101101100101010101001101101101010011010101101001101010101100" +
|
||||
"110101101010100110101101010011011011010100101010110100110110101101001010110110100101" +
|
||||
"010101100110110101011001010110101100101010110110010110010101011010011010101101100110" +
|
||||
"101010100101101011011001011010101001101101010101001001001011010101001101010010010010" +
|
||||
"101101010011010100100100101101101010010101001001001010101101001101010010010010110101" +
|
||||
"101001010010110110100000");
|
||||
|
||||
doTest("`abcdefghijklmnopqrstuvwxyz{|}~",
|
||||
"000001001011011010101001001001011001101010101001010010010110101001011010010100100101" +
|
||||
"011010010110100101001001011011010010101001010010010101011001011010010100100101101011" +
|
||||
"001010100101001001010110110010101001010010010101010011011010010100100101101010011010" +
|
||||
"100101001001010110100110101001010010010101011001101010010100100101101010100110100101" +
|
||||
"001001010110101001101001010010010110110101001010010100100101010110100110100101001001" +
|
||||
"011010110100101001010010010101101101001010010100100101010101100110100101001001011010" +
|
||||
"101100101001010010010101101011001010010100100101010110110010100101001001011001010101" +
|
||||
"101001010010010100110101011010010100100101100110101010100101001001010010110101101001" +
|
||||
"010010010110010110101010010100100101001101101010101001001001010110110100101010010010" +
|
||||
"010101010110011010100100100101101010110010101001001001010110101100101010010010010101" +
|
||||
"011011001010010110110100000");
|
||||
}
|
||||
|
||||
private static void doTest(String input, CharSequence expected) throws WriterException {
|
||||
BitMatrix result = new Code39Writer().encode(input, BarcodeFormat.CODE_39, 0, 0);
|
||||
assertEquals(expected, BitMatrixTestCase.matrixToString(result));
|
||||
assertEquals(input, expected, BitMatrixTestCase.matrixToString(result));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue