1<?php
2/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
3
4/**
5 * Image_Barcode2_Driver_Postnet class
6 *
7 * Renders PostNet barcodes
8 *
9 * PHP versions 5
10 *
11 * LICENSE: This source file is subject to version 3.0 of the PHP license
12 * that is available through the world-wide-web at the following URI:
13 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
14 * the PHP License and are unable to obtain it through the web, please
15 * send a note to license@php.net so we can mail you a copy immediately.
16 *
17 * @category  Image
18 * @package   Image_Barcode2
19 * @author    Josef "Jeff" Sipek <jeffpc@optonline.net>
20 * @copyright 2005 Josef "Jeff" Sipek
21 * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
22 * @link      http://pear.php.net/package/Image_Barcode2
23 */
24
25 /*
26  * Note:
27  *
28  * The generated barcode must fit the following criteria to be useable
29  * by the USPS scanners:
30  *
31  * When printed, the dimensions should be:
32  *
33  *     tall bar:       1/10 inches     = 2.54 mm
34  *  short bar:      1/20 inches     = 1.27 mm
35  *  density:        22 bars/inch    = 8.66 bars/cm
36  */
37
38require_once 'Image/Barcode2/Driver.php';
39require_once 'Image/Barcode2/Common.php';
40require_once 'Image/Barcode2/DualHeight.php';
41require_once 'Image/Barcode2/Exception.php';
42
43/**
44 * PostNet
45 *
46 * Package which provides a method to create PostNet barcode using GD library.
47 *
48 * @category  Image
49 * @package   Image_Barcode2
50 * @author    Josef "Jeff" Sipek <jeffpc@optonline.net>
51 * @copyright 2005 Josef "Jeff" Sipek
52 * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
53 * @version   Release: @package_version@
54 * @link      http://pear.php.net/package/Image_Barcode2
55 */
56class Image_Barcode2_Driver_Postnet extends Image_Barcode2_Common implements Image_Barcode2_Driver, Image_Barcode2_DualHeight
57{
58    /**
59     * Bar short height
60     *
61     * @var integer
62     */
63    private $_barshortheight = 7;
64
65    /**
66     * Bar tall height
67     *
68     * @var integer
69     */
70    private $_bartallheight = 15;
71
72    /**
73     * Coding map
74     * @var array
75     */
76    private $_codingmap = array(
77        '0' => '11000',
78        '1' => '00011',
79        '2' => '00101',
80        '3' => '00110',
81        '4' => '01001',
82        '5' => '01010',
83        '6' => '01100',
84        '7' => '10001',
85        '8' => '10010',
86        '9' => '10100'
87    );
88
89    /**
90     * Class constructor
91     *
92     * @param Image_Barcode2_Writer $writer Library to use.
93     */
94    public function __construct(Image_Barcode2_Writer $writer)
95    {
96        parent::__construct($writer);
97        $this->setBarcodeWidth(2);
98    }
99
100
101    /**
102     * Validate barcode
103     *
104     * @return void
105     * @throws Image_Barcode2_Exception
106     */
107    public function validate()
108    {
109        // Check barcode for invalid characters
110        if (!preg_match('/^[0-9]+$/', $this->getBarcode())) {
111            throw new Image_Barcode2_Exception('Invalid barcode');
112        }
113    }
114
115
116    /**
117     * Draws a PostNet image barcode
118     *
119     * @return resource            The corresponding PostNet image barcode
120     *
121     * @access public
122     *
123     * @author Josef "Jeff" Sipek <jeffpc@optonline.net>
124     * @since  Image_Barcode2 0.3
125     */
126    public function draw()
127    {
128        $text   = $this->getBarcode();
129        $writer = $this->getWriter();
130
131        // Calculate the barcode width
132        $barcodewidth = (strlen($text)) * 2 * 5 * $this->getBarcodeWidth()
133            + $this->getBarcodeWidth() * 3;
134
135        // Create the image
136        $img = $writer->imagecreate($barcodewidth, $this->_bartallheight);
137
138        // Alocate the black and white colors
139        $black = $writer->imagecolorallocate($img, 0, 0, 0);
140        $white = $writer->imagecolorallocate($img, 255, 255, 255);
141
142        // Fill image with white color
143        $writer->imagefill($img, 0, 0, $white);
144
145        // Initiate x position
146        $xpos = 0;
147
148        // Draws the leader
149        $writer->imagefilledrectangle(
150            $img,
151            $xpos,
152            0,
153            $xpos + $this->getBarcodeWidth() - 1,
154            $this->_bartallheight,
155            $black
156        );
157
158        $xpos += 2 * $this->getBarcodeWidth();
159
160        // Draw $text contents
161        for ($idx = 0, $all = strlen($text); $idx < $all; $idx++) {
162            $char = substr($text, $idx, 1);
163
164            for ($baridx = 0; $baridx < 5; $baridx++) {
165                $elementheight = $this->_barshortheight;
166
167                if (substr($this->_codingmap[$char], $baridx, 1)) {
168                    $elementheight = 0;
169                }
170
171                $writer->imagefilledrectangle(
172                    $img,
173                    $xpos,
174                    $elementheight,
175                    $xpos + $this->getBarcodeWidth() - 1,
176                    $this->_bartallheight,
177                    $black
178                );
179
180                $xpos += 2 * $this->getBarcodeWidth();
181            }
182        }
183
184        // Draws the trailer
185        $writer->imagefilledrectangle(
186            $img,
187            $xpos,
188            0,
189            $xpos + $this->getBarcodeWidth() - 1,
190            $this->_bartallheight,
191            $black
192        );
193
194        return $img;
195    }
196
197} // class
198