mirror of
https://github.com/zxing/zxing.git
synced 2025-02-02 05:41:08 -08:00
Issue 849, adjusted fix to Code128Writer
git-svn-id: https://zxing.googlecode.com/svn/trunk@1803 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
2d17cf4491
commit
e9d5024e46
|
@ -16,7 +16,10 @@
|
||||||
|
|
||||||
package com.google.zxing.oned;
|
package com.google.zxing.oned;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.WriterException;
|
import com.google.zxing.WriterException;
|
||||||
import com.google.zxing.common.BitMatrix;
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
@ -28,85 +31,131 @@ import com.google.zxing.common.BitMatrix;
|
||||||
*/
|
*/
|
||||||
public final class Code128Writer extends UPCEANWriter {
|
public final class Code128Writer extends UPCEANWriter {
|
||||||
|
|
||||||
public BitMatrix encode(String contents,
|
private static final int CODE_START_B = 104;
|
||||||
BarcodeFormat format,
|
private static final int CODE_START_C = 105;
|
||||||
int width,
|
private static final int CODE_CODE_B = 100;
|
||||||
int height,
|
private static final int CODE_CODE_C = 99;
|
||||||
Hashtable hints) throws WriterException {
|
private static final int CODE_STOP = 106;
|
||||||
if (format != BarcodeFormat.CODE_128) {
|
|
||||||
throw new IllegalArgumentException("Can only encode CODE_128, but got " + format);
|
public BitMatrix encode(String contents,
|
||||||
}
|
BarcodeFormat format,
|
||||||
return super.encode(contents, format, width, height, hints);
|
int width,
|
||||||
|
int height,
|
||||||
|
Hashtable hints) throws WriterException {
|
||||||
|
if (format != BarcodeFormat.CODE_128) {
|
||||||
|
throw new IllegalArgumentException("Can only encode CODE_128, but got " + format);
|
||||||
}
|
}
|
||||||
|
return super.encode(contents, format, width, height, hints);
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] encode(String contents) {
|
public byte[] encode(String contents) {
|
||||||
int length = contents.length();
|
int length = contents.length();
|
||||||
if (length > 80) {
|
// Check length
|
||||||
throw new IllegalArgumentException(
|
if (length < 1 || length > 80) {
|
||||||
"Requested contents should be less than 80 digits long, but got " + length);
|
throw new IllegalArgumentException(
|
||||||
|
"Contents length should be between 1 and 80 characters, but got " + length);
|
||||||
|
}
|
||||||
|
// Check content
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
char c = contents.charAt(i);
|
||||||
|
if (c < ' ' || c > '~') {
|
||||||
|
throw new IllegalArgumentException("Contents should only contain characters between ' ' and '~'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector patterns = new Vector(); // temporary storage for patterns
|
||||||
|
int checkSum = 0;
|
||||||
|
int checkWeight = 1;
|
||||||
|
int codeSet = 0; // selected code (CODE_CODE_B or CODE_CODE_C)
|
||||||
|
int position = 0; // position in contents
|
||||||
|
|
||||||
|
while (position < length) {
|
||||||
|
//Select code to use
|
||||||
|
int requiredDigitCount = codeSet == CODE_CODE_C ? 2 : 4;
|
||||||
|
int newCodeSet;
|
||||||
|
if (length - position >= requiredDigitCount && isDigits(contents, position, requiredDigitCount)) {
|
||||||
|
newCodeSet = CODE_CODE_C;
|
||||||
|
} else {
|
||||||
|
newCodeSet = CODE_CODE_B;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Determine which code we should use (C or B)
|
//Get the pattern index
|
||||||
boolean useCodeC = true;
|
int patternIndex;
|
||||||
for (int i = 0; i < length; i++) {
|
if (newCodeSet == codeSet) {
|
||||||
char c = contents.charAt(i);
|
// Encode the current character
|
||||||
if (c < '0' || c > '9') {
|
if (codeSet == CODE_CODE_B) {
|
||||||
useCodeC = false;
|
patternIndex = contents.charAt(position) - ' ';
|
||||||
break;
|
position += 1;
|
||||||
}
|
} else { // CODE_CODE_C
|
||||||
}
|
patternIndex = Integer.parseInt(contents.substring(position, position + 2));
|
||||||
|
position += 2;
|
||||||
int codeWidth = 11 + 11 + 13; //start plus check plus stop character
|
|
||||||
byte[] result;
|
|
||||||
int pos;
|
|
||||||
int check;
|
|
||||||
|
|
||||||
if (useCodeC) {
|
|
||||||
//Optionnaly add "0" to have pairs
|
|
||||||
if (length % 2 != 0) {
|
|
||||||
contents = '0' + contents;
|
|
||||||
length++;
|
|
||||||
}
|
|
||||||
//get total code width for this barcode
|
|
||||||
for (int i = 0; i < length; i += 2){
|
|
||||||
int[] patterns = Code128Reader.CODE_PATTERNS[Integer.parseInt(contents.substring(i, i + 2))];
|
|
||||||
for (int j = 0; j < patterns.length; j++) {
|
|
||||||
codeWidth += patterns[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = new byte[codeWidth];
|
|
||||||
pos = appendPattern(result, 0, Code128Reader.CODE_PATTERNS[105], 1);
|
|
||||||
check = 105;
|
|
||||||
//append next character to bytematrix
|
|
||||||
for (int i = 0; i < length; i += 2) {
|
|
||||||
int pair = Integer.parseInt(contents.substring(i, i + 2));
|
|
||||||
check += pair * (i / 2 + 1);
|
|
||||||
pos += appendPattern(result, pos, Code128Reader.CODE_PATTERNS[pair],1);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//get total code width for this barcode
|
// Should we change the current code?
|
||||||
for (int i = 0; i < length; i++) {
|
// Do we have a code set?
|
||||||
int[] patterns = Code128Reader.CODE_PATTERNS[contents.charAt(i) - ' '];
|
if (codeSet == 0) {
|
||||||
for (int j = 0; j < patterns.length; j++) {
|
// No, we don't have a code set
|
||||||
codeWidth += patterns[j];
|
if (newCodeSet == CODE_CODE_B) {
|
||||||
|
patternIndex = CODE_START_B;
|
||||||
|
} else {
|
||||||
|
// CODE_CODE_C
|
||||||
|
patternIndex = CODE_START_C;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Yes, we have a code set
|
||||||
|
patternIndex = newCodeSet;
|
||||||
}
|
}
|
||||||
result = new byte[codeWidth];
|
codeSet = newCodeSet;
|
||||||
pos = appendPattern(result, 0, Code128Reader.CODE_PATTERNS[104], 1);
|
|
||||||
check = 104;
|
|
||||||
//append next character to bytematrix
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
check += (contents.charAt(i) - ' ') * (i + 1);
|
|
||||||
pos += appendPattern(result, pos, Code128Reader.CODE_PATTERNS[contents.charAt(i) - ' '],1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//compute checksum and append it along with end character and quiet space
|
// Get the pattern
|
||||||
check %= 103;
|
patterns.addElement(Code128Reader.CODE_PATTERNS[patternIndex]);
|
||||||
pos += appendPattern(result,pos,Code128Reader.CODE_PATTERNS[check],1);
|
|
||||||
pos += appendPattern(result,pos,Code128Reader.CODE_PATTERNS[106],1);
|
// Compute checksum
|
||||||
|
checkSum += patternIndex * checkWeight;
|
||||||
return result;
|
if (position != 0) {
|
||||||
|
checkWeight++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute and append checksum
|
||||||
|
checkSum %= 103;
|
||||||
|
patterns.addElement(Code128Reader.CODE_PATTERNS[checkSum]);
|
||||||
|
|
||||||
|
// Append stop code
|
||||||
|
patterns.addElement(Code128Reader.CODE_PATTERNS[CODE_STOP]);
|
||||||
|
|
||||||
|
// Compute code width
|
||||||
|
int codeWidth = 0;
|
||||||
|
Enumeration patternEnumeration = patterns.elements();
|
||||||
|
while (patternEnumeration.hasMoreElements()) {
|
||||||
|
int[] pattern = (int[]) patternEnumeration.nextElement();
|
||||||
|
for (int i = 0; i < pattern.length; i++) {
|
||||||
|
codeWidth += pattern[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute result
|
||||||
|
byte[] result = new byte[codeWidth];
|
||||||
|
patternEnumeration = patterns.elements();
|
||||||
|
int pos = 0;
|
||||||
|
while (patternEnumeration.hasMoreElements()) {
|
||||||
|
int[] pattern = (int[]) patternEnumeration.nextElement();
|
||||||
|
pos += appendPattern(result, pos, pattern, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDigits(String value, int start, int length) {
|
||||||
|
int end = start + length;
|
||||||
|
for (int i = start; i < end; i++) {
|
||||||
|
char c = value.charAt(i);
|
||||||
|
if (c < '0' || c > '9') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue