KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > krysalis > barcode > impl > Code128LogicImpl


1 /*
2  * $Id: Code128LogicImpl.java,v 1.7 2003/04/17 12:21:38 jmaerki Exp $
3  * ============================================================================
4  * The Krysalis Patchy Software License, Version 1.1_01
5  * Copyright (c) 2002-2003 Nicola Ken Barozzi. All rights reserved.
6  *
7  * This Licence is compatible with the BSD licence as described and
8  * approved by http://www.opensource.org/, and is based on the
9  * Apache Software Licence Version 1.1.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in
20  * the documentation and/or other materials provided with the
21  * distribution.
22  *
23  * 3. The end-user documentation included with the redistribution,
24  * if any, must include the following acknowledgment:
25  * "This product includes software developed for project
26  * Krysalis (http://www.krysalis.org/)."
27  * Alternately, this acknowledgment may appear in the software itself,
28  * if and wherever such third-party acknowledgments normally appear.
29  *
30  * 4. The names "Krysalis" and "Nicola Ken Barozzi" and
31  * "Krysalis Barcode" must not be used to endorse or promote products
32  * derived from this software without prior written permission. For
33  * written permission, please contact nicolaken@krysalis.org.
34  *
35  * 5. Products derived from this software may not be called "Krysalis",
36  * "Krysalis Barcode", nor may "Krysalis" appear in their name,
37  * without prior written permission of Nicola Ken Barozzi.
38  *
39  * 6. This software may contain voluntary contributions made by many
40  * individuals, who decided to donate the code to this project in
41  * respect of this licence, and was originally created by
42  * Jeremias Maerki <jeremias@maerki.org>.
43  *
44  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
45  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47  * DISCLAIMED. IN NO EVENT SHALL THE KRYSALIS PROJECT OR
48  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
51  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55  * SUCH DAMAGE.
56  * ====================================================================
57  */

58 package org.krysalis.barcode.impl;
59
60 import org.krysalis.barcode.BarGroup;
61 import org.krysalis.barcode.ClassicBarcodeLogicHandler;
62
63 /**
64  * This class is an implementation of the Code 128 barcode.
65  *
66  * @author Jeremias Maerki
67  */

68 public class Code128LogicImpl {
69
70     /** The function 1 command. ASCII: 0xF1 */
71     public static final char FNC_1 = 0xF1;
72     /** The function 2 command. ASCII: 0xF2 */
73     public static final char FNC_2 = 0xF2;
74     /** The function 3 command. ASCII: 0xF3 */
75     public static final char FNC_3 = 0xF3;
76     /** The function 4 command. ASCII: 0xF4 */
77     public static final char FNC_4 = 0xF4;
78
79     private static final byte[][] CHARSET =
80                                       {{2, 1, 2, 2, 2, 2}, //000, SP, #032
81
{2, 2, 2, 1, 2, 2},
82                                        {2, 2, 2, 2, 2, 1},
83                                        {1, 2, 1, 2, 2, 3},
84                                        {1, 2, 1, 3, 2, 2},
85                                        {1, 3, 1, 2, 2, 2},
86                                        {1, 2, 2, 2, 1, 3},
87                                        {1, 2, 2, 3, 1, 2},
88                                        {1, 3, 2, 2, 1, 2},
89                                        {2, 2, 1, 2, 1, 3},
90                                        {2, 2, 1, 3, 1, 2},
91                                        {2, 3, 1, 2, 1, 2},
92                                        {1, 1, 2, 2, 3, 2},
93                                        {1, 2, 2, 1, 3, 2},
94                                        {1, 2, 2, 2, 3, 1},
95                                        {1, 1, 3, 2, 2, 2},
96                                        {1, 2, 3, 1, 2, 2}, //016, '0', #048
97
{1, 2, 3, 2, 2, 1},
98                                        {2, 2, 3, 2, 1, 1},
99                                        {2, 2, 1, 1, 3, 2},
100                                        {2, 2, 1, 2, 3, 1},
101                                        {2, 1, 3, 2, 1, 2},
102                                        {2, 2, 3, 1, 1, 2},
103                                        {3, 1, 2, 1, 3, 1},
104                                        {3, 1, 1, 2, 2, 2},
105                                        {3, 2, 1, 1, 2, 2}, //025, '9', #057
106
{3, 2, 1, 2, 2, 1}, //026, ':', #058
107
{3, 1, 2, 2, 1, 2},
108                                        {3, 2, 2, 1, 1, 2},
109                                        {3, 2, 2, 2, 1, 1},
110                                        {2, 1, 2, 1, 2, 3},
111                                        {2, 1, 2, 3, 2, 1},
112                                        {2, 3, 2, 1, 2, 1},
113                                        {1, 1, 1, 3, 2, 3}, //033, 'A', #065
114
{1, 3, 1, 1, 2, 3},
115                                        {1, 3, 1, 3, 2, 1},
116                                        {1, 1, 2, 3, 1, 3},
117                                        {1, 3, 2, 1, 1, 3},
118                                        {1, 3, 2, 3, 1, 1},
119                                        {2, 1, 1, 3, 1, 3},
120                                        {2, 3, 1, 1, 1, 3},
121                                        {2, 3, 1, 3, 1, 1},
122                                        {1, 1, 2, 1, 3, 3},
123                                        {1, 1, 2, 3, 3, 1},
124                                        {1, 3, 2, 1, 3, 1},
125                                        {1, 1, 3, 1, 2, 3},
126                                        {1, 1, 3, 3, 2, 1},
127                                        {1, 3, 3, 1, 2, 1},
128                                        {3, 1, 3, 1, 2, 1},
129                                        {2, 1, 1, 3, 3, 1},
130                                        {2, 3, 1, 1, 3, 1},
131                                        {2, 1, 3, 1, 1, 3},
132                                        {2, 1, 3, 3, 1, 1},
133                                        {2, 1, 3, 1, 3, 1},
134                                        {3, 1, 1, 1, 2, 3},
135                                        {3, 1, 1, 3, 2, 1},
136                                        {3, 3, 1, 1, 2, 1},
137                                        {3, 1, 2, 1, 1, 3},
138                                        {3, 1, 2, 3, 1, 1}, //058, 'Z', #090
139
{3, 3, 2, 1, 1, 1}, //059, '[', #091
140
{3, 1, 4, 1, 1, 1},
141                                        {2, 2, 1, 4, 1, 1},
142                                        {4, 3, 1, 1, 1, 1},
143                                        {1, 1, 1, 2, 2, 4}, //063, '_', #095
144
{1, 1, 1, 4, 2, 2}, //064, A:NUL/B:'`', #000/#096
145
{1, 2, 1, 1, 2, 4}, //065, A:SOH/B:'a'. #001/#097
146
{1, 2, 1, 4, 2, 1},
147                                        {1, 4, 1, 1, 2, 2},
148                                        {1, 4, 1, 2, 2, 1},
149                                        {1, 1, 2, 2, 1, 4},
150                                        {1, 1, 2, 4, 1, 2},
151                                        {1, 2, 2, 1, 1, 4},
152                                        {1, 2, 2, 4, 1, 1},
153                                        {1, 4, 2, 1, 1, 2},
154                                        {1, 4, 2, 2, 1, 1},
155                                        {2, 4, 1, 2, 1, 1},
156                                        {2, 2, 1, 1, 1, 4},
157                                        {4, 1, 3, 1, 1, 1},
158                                        {2, 4, 1, 1, 1, 2},
159                                        {1, 3, 4, 1, 1, 1},
160                                        {1, 1, 1, 2, 4, 2},
161                                        {1, 2, 1, 1, 4, 2},
162                                        {1, 2, 1, 2, 4, 1},
163                                        {1, 1, 4, 2, 1, 2},
164                                        {1, 2, 4, 1, 1, 2},
165                                        {1, 2, 4, 2, 1, 1},
166                                        {4, 1, 1, 2, 1, 2},
167                                        {4, 2, 1, 1, 1, 2},
168                                        {4, 2, 1, 2, 1, 1},
169                                        {2, 1, 2, 1, 4, 1},
170                                        {2, 1, 4, 1, 2, 1}, //090, A:SUB/B:'z', #026/#122
171
{4, 1, 2, 1, 2, 1},
172                                        {1, 1, 1, 1, 4, 3},
173                                        {1, 1, 1, 3, 4, 1},
174                                        {1, 3, 1, 1, 4, 1}, //094, A:RS/B:tilde, #030/#126
175
{1, 1, 4, 1, 1, 3}, //095, A:US/B:DEL, #031/#127
176
{1, 1, 4, 3, 1, 1},
177                                        {4, 1, 1, 1, 1, 3},
178                                        {4, 1, 1, 3, 1, 1},
179                                        {1, 1, 3, 1, 4, 1},
180                                        {1, 1, 4, 1, 3, 1},
181                                        {3, 1, 1, 1, 4, 1},
182                                        {4, 1, 1, 1, 3, 1},
183                                        {2, 1, 1, 4, 1, 2}, //103, Start A
184
{2, 1, 1, 2, 1, 4}, //104, Start B
185
{2, 1, 1, 2, 3, 2}};//105, Start C
186

187     private static final byte[] STOP = {2, 3, 3, 1, 1, 1, 2}; //106, STOP
188

189
190     /**
191      * Determines whether a character can be encoded in Code 128.
192      * @param ch the character to check
193      * @return true if it is a valid character
194      */

195     public static boolean isValidChar(char ch) {
196         return (ch >= 0 && ch <= 127)
197             || (ch >= FNC_1 && ch <= FNC_4);
198     }
199
200     /**
201      * Determines whether a character is defined in codeset A.
202      * @param ch the character to check
203      * @return true if it is found in codeset A
204      */

205     public static boolean isInCodeSetA(char ch) {
206         return (ch >= 0 && ch <= 95)
207             || (ch >= FNC_1 && ch <= FNC_4);
208     }
209
210     /**
211      * Determines whether a character is defined in codeset B.
212      * @param ch the character to check
213      * @return true if it is found in codeset B
214      */

215     public static boolean isInCodeSetB(char ch) {
216         return (ch >= 32 && ch <= 127)
217             || (ch >= FNC_1 && ch <= FNC_4);
218     }
219
220     /**
221      * Determines whether a character is a digit or a function 1 command.
222      * @param ch the character to check
223      * @return true if the above condition is met
224      */

225     public static boolean canBeInCodeSetC(char ch) {
226         return (ch >= '0' && ch <= '9') || (ch == FNC_1);
227     }
228     
229     /**
230      * Converts a character set index to a String representation. This is
231      * primarily used for debugging purposes.
232      * @param index the character set index
233      * @return the String representation
234      */

235     public static String JavaDoc symbolCharToString(int index) {
236         switch (index) {
237             case 96: return "FNC3/96";
238             case 97: return "FNC2/97";
239             case 98: return "Shift/98";
240             case 99: return "CodeC/99";
241             case 100: return "CodeB/FNC4";
242             case 101: return "CodeA/FNC4";
243             case 102: return "FNC1";
244             case 103: return "StartA";
245             case 104: return "StartB";
246             case 105: return "StartC";
247             default: return "idx" + Integer.toString(index);
248         }
249     }
250
251     /**
252      * Converts an encoded Code 128 message into a String for debugging
253      * purposes.
254      * @param encodedMsg the encoded message
255      * @return the String representation
256      */

257     public static String JavaDoc toString(int[] encodedMsg) {
258         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
259         for (int i = 0; i < encodedMsg.length; i++) {
260             if (i > 0) {
261                 sb.append("|");
262             }
263             sb.append(symbolCharToString(encodedMsg[i]));
264         }
265         return sb.toString();
266     }
267
268     /**
269      * Encodes a character.
270      * @param logic LogicHandler to send the barcode events to
271      * @param index index withing the character set of the character to encode
272      */

273     protected void encodeChar(ClassicBarcodeLogicHandler logic, int index) {
274         logic.startBarGroup(BarGroup.MSG_CHARACTER, symbolCharToString(index));
275         for (byte i = 0; i < 6; i++) {
276             final int width = CHARSET[index][i];
277             final boolean black = ((i % 2) == 0);
278             logic.addBar(black, width);
279         }
280         logic.endBarGroup();
281     }
282
283     /**
284      * Encodes the special stop character.
285      * @param logic LogicHandler to send the barcode events to
286      */

287     protected void encodeStop(ClassicBarcodeLogicHandler logic) {
288         logic.startBarGroup(BarGroup.STOP_CHARACTER, null);
289         for (byte i = 0; i < 7; i++) {
290             final int width = STOP[i];
291             final boolean black = ((i % 2) == 0);
292             logic.addBar(black, width);
293         }
294         logic.endBarGroup();
295     }
296
297     /**
298      * Returns the encoder to be used. The encoder is responsible for turning
299      * a String message into an array of character set indexes.
300      * <p>
301      * Override this method to supply your own implementation.
302      * @return the requested encoder
303      */

304     protected Code128Encoder getEncoder() {
305         return new DefaultCode128Encoder();
306     }
307
308     /**
309      * Encodes a message into an array of character set indexes.
310      * @param msg the message to encode
311      * @return the requested array of character set indexes
312      * @see #getEncoder()
313      */

314     public int[] createEncodedMessage(String JavaDoc msg) {
315         return getEncoder().encode(msg);
316     }
317
318     /**
319      * Generates the barcode logic
320      * @param logic the logic handler to receive the generated events
321      * @param msg the message to encode
322      */

323     public void generateBarcodeLogic(ClassicBarcodeLogicHandler logic, String JavaDoc msg) {
324         logic.startBarcode(msg);
325         
326         int[] encodedMsg = createEncodedMessage(msg);
327         for (int i = 0; i < encodedMsg.length; i++) {
328             encodeChar(logic, encodedMsg[i]);
329         }
330         
331         //Calculate checksum
332
int checksum = encodedMsg[0];
333         for (int i = 1; i < encodedMsg.length; i++) {
334             checksum += i * encodedMsg[i];
335         }
336         checksum = checksum % 103;
337         encodeChar(logic, checksum);
338         
339         encodeStop(logic);
340
341         logic.endBarcode();
342     }
343
344 }
345
Popular Tags