001    /**
002     *  This library is free software; you can redistribute it and/or modify it
003     *  under the terms of the GNU Lesser General Public License (LGPL) as
004     *  published by the Free Software Foundation; either version 3.0 of the
005     *  License, or (at your option) any later version.
006     *
007     *  This library is distributed in the hope that it will be useful, but
008     *  WITHOUT ANY WARRANTY; without even the implied warranty of
009     *  MERCHANTABILITY of FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010     *  Lesser General Public License for more details. 
011     */
012    
013    /**
014     * Title:        JBarcodeBean
015     * Description:  Barcode JavaBeans Component
016     * Copyright:    Copyright (C) 2004
017     * Company:      Matthias Hanisch
018     */
019    package net.sourceforge.jbarcodebean.model;
020    
021    import java.util.ArrayList;
022    
023    import net.sourceforge.jbarcodebean.BarcodeElement;
024    import net.sourceforge.jbarcodebean.BarcodeException;
025    import net.sourceforge.jbarcodebean.EncodedBarcode;
026    
027    
028    public class Code93 extends AbstractBarcodeStrategy {
029        
030        protected static final char SHIFT_DOLLAR  =(char)1043;
031        protected static final char SHIFT_PERCENT =(char)1044;
032        protected static final char SHIFT_SLASH   =(char)1045;
033        protected static final char SHIFT_PLUS    =(char)1046;    
034        
035        static final CharacterCode[] codes={
036            new CharacterCode('0',new byte[]{1,3,1,1,1,2},0),
037            new CharacterCode('1',new byte[]{1,1,1,2,1,3},1),
038            new CharacterCode('2',new byte[]{1,1,1,3,1,2},2),
039            new CharacterCode('3',new byte[]{1,1,1,4,1,1},3),
040            new CharacterCode('4',new byte[]{1,2,1,1,1,3},4),
041            new CharacterCode('5',new byte[]{1,2,1,2,1,2},5),
042            new CharacterCode('6',new byte[]{1,2,1,3,1,1},6),
043            new CharacterCode('7',new byte[]{1,1,1,1,1,4},7),
044            new CharacterCode('8',new byte[]{1,3,1,2,1,1},8),
045            new CharacterCode('9',new byte[]{1,4,1,1,1,1},9),
046            new CharacterCode('A',new byte[]{2,1,1,1,1,3},10),
047            new CharacterCode('B',new byte[]{2,1,1,2,1,2},11),
048            new CharacterCode('C',new byte[]{2,1,1,3,1,1},12),
049            new CharacterCode('D',new byte[]{2,2,1,1,1,2},13),
050            new CharacterCode('E',new byte[]{2,2,1,2,1,1},14),
051            new CharacterCode('F',new byte[]{2,3,1,1,1,1},15),
052            new CharacterCode('G',new byte[]{1,1,2,1,1,3},16),
053            new CharacterCode('H',new byte[]{1,1,2,2,1,2},17),
054            new CharacterCode('I',new byte[]{1,1,2,3,1,1},18),
055            new CharacterCode('J',new byte[]{1,2,2,1,1,2},19),
056            new CharacterCode('K',new byte[]{1,3,2,1,1,1},20),
057            new CharacterCode('L',new byte[]{1,1,1,1,2,3},21),
058            new CharacterCode('M',new byte[]{1,1,1,2,2,2},22),
059            new CharacterCode('N',new byte[]{1,1,1,3,2,1},23),
060            new CharacterCode('O',new byte[]{1,2,1,1,2,2},24),
061            new CharacterCode('P',new byte[]{1,3,1,1,2,1},25),
062            new CharacterCode('Q',new byte[]{2,1,2,1,1,2},26),
063            new CharacterCode('R',new byte[]{2,1,2,2,1,1},27),
064            new CharacterCode('S',new byte[]{2,1,1,1,2,2},28),
065            new CharacterCode('T',new byte[]{2,1,1,2,2,1},29),
066            new CharacterCode('U',new byte[]{2,2,1,1,2,1},30),
067            new CharacterCode('V',new byte[]{2,2,2,1,1,1},31),
068            new CharacterCode('W',new byte[]{1,1,2,1,2,2},32),
069            new CharacterCode('X',new byte[]{1,1,2,2,2,1},33),
070            new CharacterCode('Y',new byte[]{1,2,2,1,2,1},34),
071            new CharacterCode('Z',new byte[]{1,2,3,1,1,1},35),
072            new CharacterCode('-',new byte[]{1,2,1,1,3,1},36),
073            new CharacterCode('.',new byte[]{3,1,1,1,1,2},37),
074            new CharacterCode(' ',new byte[]{3,1,1,2,1,1},38),
075            new CharacterCode('$',new byte[]{3,2,1,1,1,1},39),
076            new CharacterCode('/',new byte[]{1,1,2,1,3,1},40),
077            new CharacterCode('+',new byte[]{1,1,3,1,2,1},41),
078            new CharacterCode('%',new byte[]{2,1,1,1,3,1},42),
079            new CharacterCode(SHIFT_DOLLAR,new byte[]{1,2,1,2,2,1},43),
080            new CharacterCode(SHIFT_PERCENT,new byte[]{3,1,2,1,1,1},44),
081            new CharacterCode(SHIFT_SLASH,new byte[]{3,1,1,1,2,1},45),
082            new CharacterCode(SHIFT_PLUS,new byte[]{1,2,2,2,1,1},46),
083            new CharacterCode('*',new byte[]{1,1,1,1,4,1},-1)
084        };
085    
086        protected String augmentWithChecksum(String text) throws BarcodeException {
087            int checksumC=0;
088            int checksumK=0;
089            int weightC=1;
090            int weightK=1;
091            for(int i=text.length()-1;i>=0;i--){
092                char c=text.charAt(i);
093                CharacterCode cc=getCharacterCode(c);
094                checksumC+=cc.check*weightC;
095                weightC++;
096                if(weightC>20){
097                    weightC=1;
098                }
099            }
100            checksumC=checksumC%47;
101            CharacterCode codeC=getCharacterCode(checksumC);
102            text+=codeC.character;
103            for(int i=text.length()-1;i>=0;i--){
104                char c=text.charAt(i);
105                CharacterCode cc=getCharacterCode(c);
106                checksumK+=cc.check*weightK;
107                weightK++;
108                if(weightK>15){
109                    weightK=1;
110                }
111            }
112            checksumK=checksumK%47;
113            CharacterCode codeK=getCharacterCode(checksumK);
114            text+=codeK.character;
115            return text;
116        }
117    
118        protected String getBarcodeLabelText(String text) {
119            return text;
120        }
121    
122        protected CharacterCode[] getCodes() {
123            return codes;
124        }
125    
126        protected byte getMarginWidth() {
127            return 11;
128        }
129    
130        protected char getStartSentinel() {
131            return '*';
132        }
133    
134        protected char getStopSentinel() {
135            return '*';
136        }
137    
138        protected boolean isInterleaved() {
139            return false;
140        }
141    
142        protected String postprocess(String text) {
143            return text;
144        }
145    
146        protected String preprocess(String text) throws BarcodeException {
147            return text;
148        }
149    
150        public int requiresChecksum() {
151            return MANDATORY_CHECKSUM;
152        }
153    
154        public EncodedBarcode encode(String textToEncode, boolean checked) throws BarcodeException {
155            EncodedBarcode ebc=super.encode(textToEncode, checked);
156            BarcodeElement[] elements = ebc.elements;
157            String barcodeLabelText = ebc.barcodeLabelText;
158            BarcodeElement terminationBar=new BarcodeElement(BarcodeElement.TYPE_BAR, 1);
159            ArrayList list=new ArrayList();
160            for(int i=0;i<elements.length;i++){
161                list.add(elements[i]);
162            }
163            list.add(list.size()-1,terminationBar);
164            BarcodeElement[] allElements=(BarcodeElement[]) list.toArray(new BarcodeElement[list.size()]);
165            return new EncodedBarcode(allElements, barcodeLabelText);
166        }
167        
168    }