KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > pdf > BarcodeCodabar


1 /*
2  * $Id: BarcodeCodabar.java 2376 2006-09-15 06:18:47Z xlv $
3  *
4  * Copyright 2002-2006 by Paulo Soares.
5  *
6  * The contents of this file are subject to the Mozilla Public License Version 1.1
7  * (the "License"); you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the License.
13  *
14  * The Original Code is 'iText, a free JAVA-PDF library'.
15  *
16  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18  * All Rights Reserved.
19  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source code
23  * where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above. If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34  *
35  * This library is free software; you can redistribute it and/or modify it
36  * under the terms of the MPL as stated above or under the terms of the GNU
37  * Library General Public License as published by the Free Software Foundation;
38  * either version 2 of the License, or any later version.
39  *
40  * This library is distributed in the hope that it will be useful, but WITHOUT
41  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43  * details.
44  *
45  * If you didn't download this code from the following link, you should check if
46  * you aren't using an obsolete version:
47  * http://www.lowagie.com/iText/
48  */

49 package com.lowagie.text.pdf;
50
51 import java.awt.Canvas JavaDoc;
52 import java.awt.Color JavaDoc;
53 import java.awt.Image JavaDoc;
54 import java.awt.image.MemoryImageSource JavaDoc;
55
56 import com.lowagie.text.Element;
57 import com.lowagie.text.ExceptionConverter;
58 import com.lowagie.text.Rectangle;
59
60 /** Implements the code codabar. The default parameters are:
61  * <pre>
62  *x = 0.8f;
63  *n = 2;
64  *font = BaseFont.createFont("Helvetica", "winansi", false);
65  *size = 8;
66  *baseline = size;
67  *barHeight = size * 3;
68  *textAlignment = Element.ALIGN_CENTER;
69  *generateChecksum = false;
70  *checksumText = false;
71  *startStopText = false;
72  * </pre>
73  *
74  * @author Paulo Soares (psoares@consiste.pt)
75  */

76 public class BarcodeCodabar extends Barcode{
77
78     /** The bars to generate the code.
79      */

80     private static final byte BARS[][] =
81     {
82         {0,0,0,0,0,1,1}, // 0
83
{0,0,0,0,1,1,0}, // 1
84
{0,0,0,1,0,0,1}, // 2
85
{1,1,0,0,0,0,0}, // 3
86
{0,0,1,0,0,1,0}, // 4
87
{1,0,0,0,0,1,0}, // 5
88
{0,1,0,0,0,0,1}, // 6
89
{0,1,0,0,1,0,0}, // 7
90
{0,1,1,0,0,0,0}, // 8
91
{1,0,0,1,0,0,0}, // 9
92
{0,0,0,1,1,0,0}, // -
93
{0,0,1,1,0,0,0}, // $
94
{1,0,0,0,1,0,1}, // :
95
{1,0,1,0,0,0,1}, // /
96
{1,0,1,0,1,0,0}, // .
97
{0,0,1,0,1,0,1}, // +
98
{0,0,1,1,0,1,0}, // a
99
{0,1,0,1,0,0,1}, // b
100
{0,0,0,1,0,1,1}, // c
101
{0,0,0,1,1,1,0} // d
102
};
103  
104     /** The index chars to <CODE>BARS</CODE>.
105      */

106     private static final String JavaDoc CHARS = "0123456789-$:/.+ABCD";
107     
108     private static final int START_STOP_IDX = 16;
109     /** Creates a new BarcodeCodabar.
110      */

111     public BarcodeCodabar() {
112         try {
113             x = 0.8f;
114             n = 2;
115             font = BaseFont.createFont("Helvetica", "winansi", false);
116             size = 8;
117             baseline = size;
118             barHeight = size * 3;
119             textAlignment = Element.ALIGN_CENTER;
120             generateChecksum = false;
121             checksumText = false;
122             startStopText = false;
123             codeType = CODABAR;
124         }
125         catch (Exception JavaDoc e) {
126             throw new ExceptionConverter(e);
127         }
128     }
129     
130     /** Creates the bars.
131      * @param text the text to create the bars
132      * @return the bars
133      */

134     public static byte[] getBarsCodabar(String JavaDoc text) {
135         text = text.toUpperCase();
136         int len = text.length();
137         if (len < 2)
138             throw new IllegalArgumentException JavaDoc("Codabar must have at least a start and stop character.");
139         if (CHARS.indexOf(text.charAt(0)) < START_STOP_IDX || CHARS.indexOf(text.charAt(len - 1)) < START_STOP_IDX)
140             throw new IllegalArgumentException JavaDoc("Codabar must have one of 'ABCD' as start/stop character.");
141         byte bars[] = new byte[text.length() * 8 - 1];
142         for (int k = 0; k < len; ++k) {
143             int idx = CHARS.indexOf(text.charAt(k));
144             if (idx >= START_STOP_IDX && k > 0 && k < len - 1)
145                 throw new IllegalArgumentException JavaDoc("In codabar, start/stop characters are only allowed at the extremes.");
146             if (idx < 0)
147                 throw new IllegalArgumentException JavaDoc("The character '" + text.charAt(k) + "' is illegal in codabar.");
148             System.arraycopy(BARS[idx], 0, bars, k * 8, 7);
149         }
150         return bars;
151     }
152     
153     public static String JavaDoc calculateChecksum(String JavaDoc code) {
154         if (code.length() < 2)
155             return code;
156         String JavaDoc text = code.toUpperCase();
157         int sum = 0;
158         int len = text.length();
159         for (int k = 0; k < len; ++k)
160             sum += CHARS.indexOf(text.charAt(k));
161         sum = (sum + 15) / 16 * 16 - sum;
162         return code.substring(0, len - 1) + CHARS.charAt(sum) + code.substring(len - 1);
163     }
164     
165     /** Gets the maximum area that the barcode and the text, if
166      * any, will occupy. The lower left corner is always (0, 0).
167      * @return the size the barcode occupies.
168      */

169     public Rectangle getBarcodeSize() {
170         float fontX = 0;
171         float fontY = 0;
172         String JavaDoc text = code;
173         if (generateChecksum && checksumText)
174             text = calculateChecksum(code);
175         if (!startStopText)
176             text = text.substring(1, text.length() - 1);
177         if (font != null) {
178             if (baseline > 0)
179                 fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size);
180             else
181                 fontY = -baseline + size;
182             fontX = font.getWidthPoint(altText != null ? altText : text, size);
183         }
184         text = code;
185         if (generateChecksum)
186             text = calculateChecksum(code);
187         byte bars[] = getBarsCodabar(text);
188         int wide = 0;
189         for (int k = 0; k < bars.length; ++k) {
190             wide += (int)bars[k];
191         }
192         int narrow = bars.length - wide;
193         float fullWidth = x * (narrow + wide * n);
194         fullWidth = Math.max(fullWidth, fontX);
195         float fullHeight = barHeight + fontY;
196         return new Rectangle(fullWidth, fullHeight);
197     }
198     
199     /** Places the barcode in a <CODE>PdfContentByte</CODE>. The
200      * barcode is always placed at coodinates (0, 0). Use the
201      * translation matrix to move it elsewhere.<p>
202      * The bars and text are written in the following colors:<p>
203      * <P><TABLE BORDER=1>
204      * <TR>
205      * <TH><P><CODE>barColor</CODE></TH>
206      * <TH><P><CODE>textColor</CODE></TH>
207      * <TH><P>Result</TH>
208      * </TR>
209      * <TR>
210      * <TD><P><CODE>null</CODE></TD>
211      * <TD><P><CODE>null</CODE></TD>
212      * <TD><P>bars and text painted with current fill color</TD>
213      * </TR>
214      * <TR>
215      * <TD><P><CODE>barColor</CODE></TD>
216      * <TD><P><CODE>null</CODE></TD>
217      * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
218      * </TR>
219      * <TR>
220      * <TD><P><CODE>null</CODE></TD>
221      * <TD><P><CODE>textColor</CODE></TD>
222      * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
223      * </TR>
224      * <TR>
225      * <TD><P><CODE>barColor</CODE></TD>
226      * <TD><P><CODE>textColor</CODE></TD>
227      * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
228      * </TR>
229      * </TABLE>
230      * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
231      * @param barColor the color of the bars. It can be <CODE>null</CODE>
232      * @param textColor the color of the text. It can be <CODE>null</CODE>
233      * @return the dimensions the barcode occupies
234      */

235     public Rectangle placeBarcode(PdfContentByte cb, Color JavaDoc barColor, Color JavaDoc textColor) {
236         String JavaDoc fullCode = code;
237         if (generateChecksum && checksumText)
238             fullCode = calculateChecksum(code);
239         if (!startStopText)
240             fullCode = fullCode.substring(1, fullCode.length() - 1);
241         float fontX = 0;
242         if (font != null) {
243             fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size);
244         }
245         byte bars[] = getBarsCodabar(generateChecksum ? calculateChecksum(code) : code);
246         int wide = 0;
247         for (int k = 0; k < bars.length; ++k) {
248             wide += (int)bars[k];
249         }
250         int narrow = bars.length - wide;
251         float fullWidth = x * (narrow + wide * n);
252         float barStartX = 0;
253         float textStartX = 0;
254         switch (textAlignment) {
255             case Element.ALIGN_LEFT:
256                 break;
257             case Element.ALIGN_RIGHT:
258                 if (fontX > fullWidth)
259                     barStartX = fontX - fullWidth;
260                 else
261                     textStartX = fullWidth - fontX;
262                 break;
263             default:
264                 if (fontX > fullWidth)
265                     barStartX = (fontX - fullWidth) / 2;
266                 else
267                     textStartX = (fullWidth - fontX) / 2;
268                 break;
269         }
270         float barStartY = 0;
271         float textStartY = 0;
272         if (font != null) {
273             if (baseline <= 0)
274                 textStartY = barHeight - baseline;
275             else {
276                 textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size);
277                 barStartY = textStartY + baseline;
278             }
279         }
280         boolean print = true;
281         if (barColor != null)
282             cb.setColorFill(barColor);
283         for (int k = 0; k < bars.length; ++k) {
284             float w = (bars[k] == 0 ? x : x * n);
285             if (print)
286                 cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight);
287             print = !print;
288             barStartX += w;
289         }
290         cb.fill();
291         if (font != null) {
292             if (textColor != null)
293                 cb.setColorFill(textColor);
294             cb.beginText();
295             cb.setFontAndSize(font, size);
296             cb.setTextMatrix(textStartX, textStartY);
297             cb.showText(fullCode);
298             cb.endText();
299         }
300         return getBarcodeSize();
301     }
302
303     /** Creates a <CODE>java.awt.Image</CODE>. This image only
304      * contains the bars without any text.
305      * @param foreground the color of the bars
306      * @param background the color of the background
307      * @return the image
308      */

309     public java.awt.Image JavaDoc createAwtImage(Color JavaDoc foreground, Color JavaDoc background) {
310         int f = foreground.getRGB();
311         int g = background.getRGB();
312         Canvas JavaDoc canvas = new Canvas JavaDoc();
313
314         String JavaDoc fullCode = code;
315         if (generateChecksum && checksumText)
316             fullCode = calculateChecksum(code);
317         if (!startStopText)
318             fullCode = fullCode.substring(1, fullCode.length() - 1);
319         byte bars[] = getBarsCodabar(generateChecksum ? calculateChecksum(code) : code);
320         int wide = 0;
321         for (int k = 0; k < bars.length; ++k) {
322             wide += (int)bars[k];
323         }
324         int narrow = bars.length - wide;
325         int fullWidth = narrow + wide * (int)n;
326         boolean print = true;
327         int ptr = 0;
328         int height = (int)barHeight;
329         int pix[] = new int[fullWidth * height];
330         for (int k = 0; k < bars.length; ++k) {
331             int w = (bars[k] == 0 ? 1 : (int)n);
332             int c = g;
333             if (print)
334                 c = f;
335             print = !print;
336             for (int j = 0; j < w; ++j)
337                 pix[ptr++] = c;
338         }
339         for (int k = fullWidth; k < pix.length; k += fullWidth) {
340             System.arraycopy(pix, 0, pix, k, fullWidth);
341         }
342         Image JavaDoc img = canvas.createImage(new MemoryImageSource JavaDoc(fullWidth, height, pix, 0, fullWidth));
343         
344         return img;
345     }
346 }
347
Popular Tags