1. Import

This commit is contained in:
2026-03-29 10:34:57 +02:00
parent b0e00c1259
commit a1129565af
4899 changed files with 3007593 additions and 0 deletions

View File

@@ -0,0 +1,218 @@
<?php
/**
* BCGBarcode.php
*--------------------------------------------------------------------
*
* Base class for Barcode 1D and 2D
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
*--------------------------------------------------------------------
* $Id: BCGBarcode.php,v 1.12 2010/02/14 00:25:14 jsgoupil Exp $
* PHP5-Revision: 1.13
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGColor.php');
class BCGBarcode { // abstract
var $COLOR_BG = 0; // const
var $COLOR_FG = 1; // const
var $error; // protected
var $colorFg, $colorBg; // Color Foreground, Barckground
var $scale; // Scale of the graphic, default: 1
var $offsetX, $offsetY; // Position where to start the drawing
function BCGBarcode() { // protected
$this->setForegroundColor(0x000000);
$this->setBackgroundColor(0xffffff);
$this->setScale(1);
$this->setOffsetX(0);
$this->setOffsetY(0);
$this->error = 0;
}
/**
* Parses the text before displaying it.
*
* @param mixed $text
*/
function parse($text) {} // public abstract
/**
* Sets the foreground color of the barcode. It could be a BCGColor
* value or simply a language code (white, black, yellow...) or hex value.
*
* @param mixed $code
*/
function setForegroundColor($code) {
if(is_a($code, 'BCGColor')) {
$this->colorFg =& $code;
} else {
$this->colorFg = new BCGColor($code);
}
}
/**
* Sets the background color of the barcode. It could be a BCGColor
* value or simply a language code (white, black, yellow...) or hex value.
*
* @param mixed $code
*/
function setBackgroundColor($code) {
if(is_a($code, 'BCGColor')) {
$this->colorBg =& $code;
} else {
$this->colorBg = new BCGColor($code);
}
}
/**
* Sets the color
*
* @param mixed $fg
* @param mixed $bg
*/
function setColor($fg, $bg) {
$this->setForegroundColor($fg);
$this->setBackgroundColor($bg);
}
function getScale() {
return $this->scale;
}
function setScale($scale) {
$scale = intval($scale);
if($scale <= 0) {
$scale = 1;
}
$this->scale = $scale;
}
function draw(&$im) {} // public abstract
/**
* Returns the maximal size of a barcode.
* [0]->width
* [1]->height
*
* @return int[]
*/
function getMaxSize() {
return array($this->offsetX * $this->scale, $this->offsetY * $this->scale);
}
/**
* Sets the X offset
*
* @param int $offsetX
*/
function setOffsetX($offsetX) {
$offsetX = intval($offsetX);
if($offsetX < 0) {
$offsetX = 0;
}
$this->offsetX = $offsetX;
}
/**
* Sets the Y offset
*
* @param int $offsetY
*/
function setOffsetY($offsetY) {
$offsetY = intval($offsetY);
if($offsetY < 0) {
$offsetY = 0;
}
$this->offsetY = $offsetY;
}
function drawPixel(&$im, $x, $y, $color = 1) { // protected
$xR = ($x + $this->offsetX) * $this->scale;
$yR = ($y + $this->offsetY) * $this->scale;
// we always draw a rectangle
imagefilledrectangle($im,
$xR,
$yR,
$xR + $this->scale - 1,
$yR + $this->scale - 1,
$this->getColor($im, $color));
}
function drawRectangle(&$im, $x1, $y1, $x2, $y2, $color = 1) { // protected
if($this->scale === 1) {
imagerectangle($im,
($x1 + $this->offsetX) * $this->scale,
($y1 + $this->offsetY) * $this->scale,
($x2 + $this->offsetX) * $this->scale,
($y2 + $this->offsetY) * $this->scale,
$this->getColor($im, $color));
} else {
imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale, ($y1 + $this->offsetY) * $this->scale, ($x2 + $this->offsetX) * $this->scale + $this->scale - 1, ($y1 + $this->offsetY) * $this->scale + $this->scale - 1, $this->getColor($im, $color));
imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale, ($y1 + $this->offsetY) * $this->scale, ($x1 + $this->offsetX) * $this->scale + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->scale - 1, $this->getColor($im, $color));
imagefilledrectangle($im, ($x2 + $this->offsetX) * $this->scale, ($y1 + $this->offsetY) * $this->scale, ($x2 + $this->offsetX) * $this->scale + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->scale - 1, $this->getColor($im, $color));
imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale, ($y2 + $this->offsetY) * $this->scale, ($x2 + $this->offsetX) * $this->scale + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->scale - 1, $this->getColor($im, $color));
}
}
function drawFilledRectangle(&$im, $x1, $y1, $x2, $y2, $color = 1) { // protected
if($x1 > $x2) { // Swap
$x1 ^= $x2 ^= $x1 ^= $x2;
}
if($y1 > $y2) { // Swap
$y1 ^= $y2 ^= $y1 ^= $y2;
}
imagefilledrectangle($im,
($x1 + $this->offsetX) * $this->scale,
($y1 + $this->offsetY) * $this->scale,
($x2 + $this->offsetX) * $this->scale + $this->scale - 1,
($y2 + $this->offsetY) * $this->scale + $this->scale - 1,
$this->getColor($im, $color));
}
function getColor(&$im, $color) { // protected
if($color === $this->COLOR_BG) {
return $this->colorBg->allocate($im);
} else {
return $this->colorFg->allocate($im);
}
}
/**
* Writes the Error on the picture
*
* @param ressource $img
* @param string $text
*/
function drawError(&$im, $text) { // protected
// Is the image big enough?
$w = imagesx($im);
$h = imagesy($im);
$text = 'Error: ' . $text;
$width = imagefontwidth(2) * strlen($text);
$height = imagefontheight(2) + $this->error * 15;
if($width > $w || $height > $h) {
$width = max($w, $width);
$height = max($h, $height);
// We change the size of the image
$newimg = imagecreatetruecolor($width, $height);
imagefill($newimg, 0, 0, imagecolorat($im, 0, 0));
imagecopy($newimg, $im, 0, 0, 0, 0, $w, $h);
$im = $newimg;
}
imagestring($im, 2, 0, $this->error * 15, $text, $this->colorFg->allocate($im));
$this->error++;
}
}
?>

View File

@@ -0,0 +1,226 @@
<?php
/**
* BCGBarcode1D.php
*--------------------------------------------------------------------
*
* Holds all type of barcodes for 1D generation
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
*--------------------------------------------------------------------
* $Id: BCGBarcode1D.php,v 1.3 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.3
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode.php');
include_once('BCGFont.php');
class BCGBarcode1D extends BCGBarcode { // abstract
var $SIZE_SPACING_FONT = 5; // const
var $AUTO_LABEL = '##!!AUTO_LABEL!!##'; // const
var $thickness;
var $keys, $code;
var $positionX;
var $textfont;
var $text, $label;
var $checksumValue;
var $displayChecksum;
function BCGBarcode1D() { // protected
BCGBarcode::BCGBarcode();
$this->setThickness(30);
$this->text = '';
$this->checksumValue = false;
$this->setLabel($this->AUTO_LABEL);
$this->setFont(5);
}
function setThickness($thickness) { // public
$this->thickness = $thickness;
}
function getThickness() { // public
return $this->thickness;
}
function parse($text) { // public
$this->text = $text;
$this->checksumValue = false; // Reset checksumValue
}
function setLabel($label) { // public
$this->label = $label;
}
function getLabel() { // public
$label = $this->label;
if($this->label === $this->AUTO_LABEL) {
$label = $this->text;
if($this->displayChecksum === true && ($checksum = $this->processChecksum()) !== false) {
$label .= $checksum;
}
}
return $label;
}
/**
* Saves the font.
*
* @param mixed $font BCGFont or int
*/
function setFont($font) { // public
if(is_a($font, 'BCGFont')) {
$this->textfont = $font; // clone
$this->textfont->setText($this->text);
} else {
$this->textfont = min(5, max(0, intval($font)));
}
}
function getMaxSize() { // public
$p = BCGBarcode::getMaxSize();
$label = $this->getLabel();
$textHeight = 0;
if(!empty($label)) {
if(is_a($this->textfont, 'BCGFont')) {
$textfont = $this->textfont; // clone
$textfont->setText($label);
$textHeight = $textfont->getHeight() + $this->SIZE_SPACING_FONT;
} elseif($this->textfont !== 0) {
$textHeight = imagefontheight($this->textfont) + $this->SIZE_SPACING_FONT;
}
}
return array($p[0], $p[1] + $this->thickness * $this->scale + $textHeight);
}
/**
* Gets the checksum of a Barcode.
* If no checksum is available, return FALSE.
*
* @return string
*/
function getChecksum() { // public
return $this->processChecksum();
}
/**
* Sets if the checksum is displayed with the label or not.
* The checksum must be activated in some case to make this variable effective.
*
* @param boolean $display
*/
function setDisplayChecksum($display) { // public
$this->displayChecksum = (bool)$display;
}
/**
* Returns the index in $keys (useful for checksum)
*
* @param mixed $var
* @return mixed
*/
function findIndex($var) { // protected
return array_search($var, $this->keys);
}
/**
* Returns the code of the char (useful for drawing bars)
*
* @param mixed $var
* @return string
*/
function findCode($var) { // protected
return $this->code[$this->findIndex($var)];
}
/**
* Draws all chars thanks to $code. if $start is true, the line begins by a space.
* if $start is false, the line begins by a bar.
*
* @param resource $im
* @param string $code
* @param boolean $start
*/
function drawChar(&$im, $code, $startBar = true) { // protected
$colors = array($this->COLOR_FG, $this->COLOR_BG);
$currentColor = $startBar ? 0 : 1;
$c = strlen($code);
for($i = 0; $i < $c; $i++) {
for($j = 0; $j < intval($code[$i]) + 1; $j++) {
$this->drawSingleBar($im, $colors[$currentColor]);
$this->nextX();
}
$currentColor = ($currentColor + 1) % 2;
}
}
/**
* Draws a Bar of $color depending of the resolution
*
* @param resource $img
* @param FColor $color
*/
function drawSingleBar(&$im, $color) { // protected
$this->drawFilledRectangle($im, $this->positionX, 0, $this->positionX, $this->thickness - 1, $color);
}
/**
* Moving the pointer right to write a bar
*/
function nextX() { // protected
$this->positionX++;
}
/**
* Draws the label under the barcode
*
* @param resource $im
*/
function drawText(&$im) { // protected
$label = $this->getLabel();
if(!empty($label)) {
$pA = $this->getMaxSize();
$pB = BCGBarcode1D::getMaxSize();
$w = $pA[0] - $pB[0];
if(is_a($this->textfont, 'BCGFont')) {
$textfont = $this->textfont; // clone
$textfont->setText($label);
$xPosition = ($w / 2) - ($textfont->getWidth() / 2) + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $textfont->getHeight() - $textfont->getUnderBaseline() + $this->SIZE_SPACING_FONT + $this->offsetY * $this->scale;
$textfont->draw($im, $this->colorFg->allocate($im), $xPosition, $yPosition);
} elseif($this->textfont !== 0) {
$xPosition = ($w / 2) - (strlen($label) / 2) * imagefontwidth($this->textfont) + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $this->SIZE_SPACING_FONT + $this->offsetY * $this->scale;
imagestring($im, $this->textfont, $xPosition, $yPosition, $label, $this->colorFg->allocate($im));
}
}
}
/**
* Method that saves FALSE into the checksumValue. This means no checksum
* but this method should be overloaded when needed.
*/
function calculateChecksum() { // protected
$this->checksumValue = false;
}
/**
* Returns FALSE because there is no checksum. This method should be
* overloaded to return correctly the checksum in string with checksumValue.
*
* @return string
*/
function processChecksum() { // protected
return false;
}
}

View File

@@ -0,0 +1,147 @@
<?php
/**
* BCGColor.php
*--------------------------------------------------------------------
*
* Holds Color in RGB Format.
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil New functionality
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGColor.php,v 1.7 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.6
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
class BCGColor {
var $r, $g, $b; // int Hexadecimal Value
/**
* Save RGB value into the classes
*
* There are 4 way to associate color with this classes :
* 1. Gives 3 parameters int (R, G, B)
* 2. Gives 1 parameter string hex value (#ff0000) (preceding with #)
* 3. Gives 1 parameter int hex value (0xff0000)
* 4. Gives 1 parameter string color code (white, black, orange...)
*
* @param mixed ...
*/
function BCGColor() {
$args = func_get_args();
$c = count($args);
if ($c === 3) {
$this->r = intval($args[0]);
$this->g = intval($args[1]);
$this->b = intval($args[2]);
} elseif ($c === 1) {
if (is_string($args[0]) && strlen($args[0]) === 7 && $args[0]{0} === '#') { // Hex Value in String
$this->r = intval(substr($args[0], 1, 2), 16);
$this->g = intval(substr($args[0], 3, 2), 16);
$this->b = intval(substr($args[0], 5, 2), 16);
} else {
if (is_string($args[0])) {
$args[0] = BCGColor::getColor($args[0]);
}
$args[0] = intval($args[0]);
$this->r = ($args[0] & 0xff0000) >> 16;
$this->g = ($args[0] & 0x00ff00) >> 8;
$this->b = ($args[0] & 0x0000ff);
}
} else {
$this->r = $this->g = $this->b = 0;
}
}
/**
* Returns Red Color
*
* @return int
*/
function r() {
return $this->r;
}
/**
* Returns Green Color
*
* @return int
*/
function g() {
return $this->g;
}
/**
* Returns Blue Color
*
* @return int
*/
function b() {
return $this->b;
}
/**
* Returns the int value for PHP color
*
* @param resource $im
* @return int
*/
function allocate(&$im) {
return imagecolorallocate($im, $this->r, $this->g, $this->b);
}
/**
* Returns class of BCGColor depending of the string color
*
* If the color doens't exist, it takes the default one.
*
* @param string $code
* @param string $default
*/
function getColor($code, $default = 'white') { // static
switch(strtolower($code)) {
case '':
case 'white':
return 0xffffff;
case 'black':
return 0x000000;
case 'maroon':
return 0x800000;
case 'red':
return 0xff0000;
case 'orange':
return 0xffa500;
case 'yellow':
return 0xffff00;
case 'olive':
return 0x808000;
case 'purple':
return 0x800080;
case 'fuchsia':
return 0xff00ff;
case 'lime':
return 0x00ff00;
case 'green':
return 0x008000;
case 'navy':
return 0x000080;
case 'blue':
return 0x0000ff;
case 'aqua':
return 0x00ffff;
case 'teal':
return 0x008080;
case 'silver':
return 0xc0c0c0;
case 'gray':
return 0x808080;
default:
return BCGColor::getColor($default, 'white');
}
}
};
?>

View File

@@ -0,0 +1,196 @@
<?php
/**
* BCGDrawing.php
*--------------------------------------------------------------------
*
* Holds the drawing $im
* You can use get_im() to add other kind of form not held into these classes.
*
*--------------------------------------------------------------------
* Revision History
* v2.1.0 8 nov 2009 Jean-Sébastien Goupil Support DPI, Rotation
* v2.0.1 8 mar 2009 Jean-Sébastien Goupil Supports GIF and WBMP
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Just one barcode per drawing
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGDrawing.php,v 1.10 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.12
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode.php');
include_once('drawer/BCGDrawJPG.php');
include_once('drawer/BCGDrawPNG.php');
class BCGDrawing {
var $IMG_FORMAT_PNG = 1; // const
var $IMG_FORMAT_JPEG = 2; // const
var $IMG_FORMAT_GIF = 3; // const
var $IMG_FORMAT_WBMP = 4; // const
var $w, $h; // int
var $color; // BCGColor
var $filename; // char *
var $im; // {object}
var $barcode; // BCGBarcode
var $dpi; // int
var $rotateDegree; // float
/**
* Constructor
*
* @param int $w
* @param int $h
* @param string filename
* @param BCGColor $color
*/
function BCGDrawing($filename, &$color) {
$this->im = null;
$this->setFilename($filename);
$this->color =& $color;
$this->dpi = null;
$this->rotateDegree = 0.0;
}
/**
* Destructor
*/
//public function __destruct() {
// $this->destroy();
//}
/**
* Sets the filename
*
* @param string $filaneme
*/
function setFilename($filename) {
$this->filename = $filename;
}
/**
* Init Image and color background
*/
function init() {
if($this->im === null) {
$this->im = imagecreatetruecolor($this->w, $this->h)
or die('Can\'t Initialize the GD Libraty');
imagefilledrectangle($this->im, 0, 0, $this->w - 1, $this->h - 1, $this->color->allocate($this->im));
}
}
/**
* @return resource
*/
function &get_im() {
return $this->im;
}
/**
* @param resource $im
*/
function set_im(&$im) {
$this->im = $im;
}
/**
* Set Barcode for drawing
*
* @param BCGBarcode $barcode
*/
function setBarcode(&$barcode) {
$this->barcode =& $barcode;
}
/**
* Get the DPI for supported filetype
*
* @return int
*/
function getDPI() {
return $this->dpi;
}
/**
* Set the DPI for supported filetype
*
* @param float $dpi
*/
function setDPI($dpi) {
$this->dpi = $dpi;
}
/**
* Get the rotation angle in degree
*
* @return float
*/
function getRotationAngle() {
return $this->rotateDegree;
}
/**
* Set the rotation angle in degree
*
* @param float $degree
*/
function setRotationAngle($degree) {
$this->rotateDegree = (float)$degree;
}
/**
* Draw the barcode on the image $im
*/
function draw() {
$size = $this->barcode->getMaxSize();
$this->w = max(1, $size[0]);
$this->h = max(1, $size[1]);
$this->init();
$this->barcode->draw($this->im);
}
/**
* Save $im into the file (many format available)
*
* @param int $image_style
* @param int $quality
*/
function finish($image_style = 2, $quality = 100) {
$drawer = null;
$im = $this->im;
if($this->rotateDegree > 0.0) {
$im = imagerotate($this->im, $this->rotateDegree, $this->color->allocate($this->im));
}
if ($image_style === $this->IMG_FORMAT_PNG) {
$drawer = new BCGDrawPNG($im);
$drawer->setFilename($this->filename);
$drawer->setDPI($this->dpi);
} elseif ($image_style === $this->IMG_FORMAT_JPEG) {
$drawer = new BCGDrawJPG($im);
$drawer->setFilename($this->filename);
$drawer->setDPI($this->dpi);
$drawer->setQuality($quality);
} elseif ($image_style === $this->IMG_FORMAT_GIF) {
imagegif($this->im, $this->filename);
} elseif ($image_style === $this->IMG_FORMAT_WBMP) {
imagewbmp($this->im, $this->filename);
}
if($drawer !== null) {
$drawer->draw();
}
}
/**
* Free the memory of PHP (called also by destructor)
*/
function destroy() {
@imagedestroy($this->im);
}
};
?>

View File

@@ -0,0 +1,102 @@
<?php
/**
* BCGFont.php
*--------------------------------------------------------------------
*
* Holds font family and size.
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3 6 feb 2006 Jean-Sébastien Goupil Correct getWidth()
* v1.2.3b 30 dec 2005 Jean-Sébastien Goupil Add getUnderBaseline()
* V1.2.1 27 jun 2005 Jean-Sebastien Goupil New
*--------------------------------------------------------------------
* $Id: BCGFont.php,v 1.6 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.7
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
class BCGFont {
var $path;
var $text;
var $size;
var $box;
/**
* Constructor
*
* @param string $fontPath path to the file
* @param int $size size in point
*/
function BCGFont($fontPath, $size) {
$this->path = $fontPath;
$this->size = $size;
}
/**
* Text associated to the font
*
* @param string text
*/
function setText($text) {
$this->text = $text;
$im = imagecreate(1, 1);
$this->box = imagettftext($im, $this->size, 0, 0, 0, imagecolorallocate($im, 0, 0, 0), $this->path, $this->text);
}
/**
* Returns the width that the text takes to be written
*
* @return float
*/
function getWidth() {
if ($this->box !== NULL) {
// Bug fixed : a number is aligned on the "right" in the box...
// If we are writting the number "1" with minX at 2 and maxX at 10
// The maxWidth will be 10 and not 8 because we don't squeeze the number
// on its left. So now we don't remove the minX.
return abs(max($this->box[2], $this->box[4]));
} else {
return 0;
}
}
/**
* Returns the height that the text takes.
*
* @return float
*/
function getHeight() {
if ($this->box !== NULL) {
return (float) abs(max($this->box[5], $this->box[7]) - min($this->box[1], $this->box[3]));
} else {
return 0.0;
}
}
/**
* Returns the number of pixel under the baseline located at 0.
*
* @return float
*/
function getUnderBaseline() {
// Y for imagettftext : This sets the position of the fonts baseline, not the very bottom of the character.
return (float) max($this->box[1], $this->box[3]);
}
/**
* Draws the text on the image at a specific position.
* $x and $y represent the left bottom corner.
*
* @param resource $im
* @param int $color
* @param int $x
* @param int $y
*/
function draw(&$im, $color, $x, $y) {
imagettftext($im, $this->size, 0, $x, $y, $color, $this->path, $this->text);
}
}
?>

View File

@@ -0,0 +1,121 @@
<?php
/**
* BCGcodabar.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - Codabar
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update + fix B and C
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil PHP5.1 compatible
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGcodabar.barcode.php,v 1.9 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.11
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGcodabar extends BCGBarcode1D {
/**
* Constructor
*/
function BCGcodabar() { // public
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9','-','$',':','/','.','+','A','B','C','D');
$this->code = array( // 0 added to add an extra space
'00000110', /* 0 */
'00001100', /* 1 */
'00010010', /* 2 */
'11000000', /* 3 */
'00100100', /* 4 */
'10000100', /* 5 */
'01000010', /* 6 */
'01001000', /* 7 */
'01100000', /* 8 */
'10010000', /* 9 */
'00011000', /* - */
'00110000', /* $ */
'10001010', /* : */
'10100010', /* / */
'10101000', /* . */
'00111110', /* + */
'00110100', /* A */
'01010010', /* B */
'00010110', /* C */
'00011100' /* D */
);
}
/**
* Saves Text
*
* @param string $text
*/
function parse($text) {
BCGBarcode1D::parse(strtoupper($text)); // Only Capital Letters are Allowed
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must start by A, B, C or D
if($this->text[0] !== 'A' && $this->text[0] !== 'B' && $this->text[0] !== 'C' && $this->text[0] !== 'D') {
$this->drawError($im, 'Must start by char A, B, C or D.');
$error_stop = true;
}
// Must over by A, B, C or D
$c2 = $c - 1;
if($c2 === 0 || ($this->text[$c2] !== 'A' && $this->text[$c2] !== 'B' && $this->text[$c2] !== 'C' && $this->text[$c2] !== 'D')) {
$this->drawError($im, 'Must end by char A, B, C or D.');
$error_stop = true;
}
if($error_stop === false) {
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->findCode($this->text[$i]), true);
}
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$w = 0;
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
$index = $this->findIndex($this->text[$i]);
if($index !== false) {
$w += 8;
$w += substr_count($this->code[$index], '1');
}
}
return array($p[0] + $w * $this->scale, $p[1]);
}
};
?>

View File

@@ -0,0 +1,164 @@
<?php
/**
* BCGcode11.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - Code 11
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 30 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible + Error in checksum
* v1.2.2 23 jul 2005 Jean-Sébastien Goupil WS Fix
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGcode11.barcode.php,v 1.9 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.11
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGcode11 extends BCGBarcode1D {
/**
* Constructor
*/
function BCGcode11() { // public
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9','-');
$this->code = array( // 0 added to add an extra space
'000010', /* 0 */
'100010', /* 1 */
'010010', /* 2 */
'110000', /* 3 */
'001010', /* 4 */
'101000', /* 5 */
'011000', /* 6 */
'000110', /* 7 */
'100100', /* 8 */
'100000', /* 9 */
'001000' /* - */
);
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im,'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Starting Code
$this->drawChar($im, '001100', true);
// Chars
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->findCode($this->text[$i]), true);
}
// Checksum
$this->calculateChecksum();
$c = count($this->checksumValue);
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->code[$this->checksumValue[$i]], true);
}
// Ending Code
$this->drawChar($im, '00110', true);
$this->drawText($im);
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$w = 0;
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
$index = $this->findIndex($this->text[$i]);
if($index !== false) {
$w += 6;
$w += substr_count($this->code[$index], '1');
}
}
$startlength = 8 * $this->scale;
$textlength = $w * $this->scale;
// We take the max length possible for checksums (it is 7 or 8...)
$checksumlength = 8 * $this->scale;
if($c >= 10) {
$checksumlength += 8 * $this->scale;
}
$endlength = 7 * $this->scale;
return array($p[0] + $startlength + $textlength + $checksumlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Checksum
// First CheckSUM "C"
// The "C" checksum character is the modulo 11 remainder of the sum of the weighted
// value of the data characters. The weighting value starts at "1" for the right-most
// data character, 2 for the second to last, 3 for the third-to-last, and so on up to 20.
// After 10, the sequence wraps around back to 1.
// Second CheckSUM "K"
// Same as CheckSUM "C" but we count the CheckSum "C" at the end
// After 9, the sequence wraps around back to 1.
$sequence_multiplier = array(10, 9);
$temp_text = $this->text;
$this->checksumValue = array();
for($z = 0; $z < 2; $z++) {
$c = strlen($temp_text);
// We don't display the K CheckSum if the original text had a length less than 10
if($c <= 10 && $z === 1) {
break;
}
$checksum = 0;
for($i = $c, $j = 0; $i > 0; $i--, $j++) {
$multiplier = $i % $sequence_multiplier[$z];
if($multiplier === 0) {
$multiplier = $sequence_multiplier[$z];
}
$checksum += $this->findIndex($temp_text[$j]) * $multiplier;
}
$this->checksumValue[$z] = $checksum % 11;
$temp_text .= $this->keys[$this->checksumValue[$z]];
}
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
$ret = '';
$c = count($this->checksumValue);
for($i = 0; $i < $c; $i++) {
$ret .= $this->keys[$this->checksumValue[$i]];
}
return $ret;
}
return false;
}
};
?>

View File

@@ -0,0 +1,874 @@
<?php
/**
* BCGcode128.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - Code 128, A, B, C
*
* # Code C Working properly only on PHP4 or PHP5.0.3+ due to bug :
* http://bugs.php.net/bug.php?id=28862
*
* !! Warning !!
* If you display the checksum on the label, you may obtain
* some garbage since some characters are not displayable.
*
*--------------------------------------------------------------------
* Revision History
* v2.1.0 8 nov 2009 Jean-Sébastien Goupil Specify exact table for encoding
* v2.0.1 8 mar 2009 Jean-Sébastien Goupil Fix Code 128 C
* v2.00 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3pl2 27 sep 2006 Jean-Sébastien Goupil There were some errors dealing with C table
* v1.2.3b 30 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added + Correct bug if passing C to another code
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGcode128.barcode.php,v 1.13 2010/02/14 00:25:14 jsgoupil Exp $
* PHP5-Revision: 1.17
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
define('CODE128_A', 1); // Table A
define('CODE128_B', 2); // Table B
define('CODE128_C', 3); // Table C
class BCGcode128 extends BCGBarcode1D {
var $KEYA_FNC3 = 96; // const
var $KEYA_FNC2 = 97; // const
var $KEYA_SHIFT = 98; // const
var $KEYA_CODEC = 99; // const
var $KEYA_CODEB = 100; // const
var $KEYA_FNC4 = 101; // const
var $KEYA_FNC1 = 102; // const
var $KEYB_FNC3 = 96; // const
var $KEYB_FNC2 = 97; // const
var $KEYB_SHIFT = 98; // const
var $KEYB_CODEC = 99; // const
var $KEYB_FNC4 = 100; // const
var $KEYB_CODEA = 101; // const
var $KEYB_FNC1 = 102; // const
var $KEYC_CODEB = 100; // const
var $KEYC_CODEA = 101; // const
var $KEYC_FNC1 = 102; // const
var $KEY_STARTA = 103; // const
var $KEY_STARTB = 104; // const
var $KEY_STARTC = 105; // const
var $KEY_STOP = 106; // const
var $keysA, $keysB, $keysC;
var $starting_text;
var $indcheck, $data;
var $tilde;
var $errorText;
var $shift;
var $latch;
var $fnc;
var $METHOD = NULL; // Array of method available to create PDF417 (PDF417_TM, PDF417_NM, PDF417_BM)
/**
* Constructor
*
* @param char $start
*/
function BCGcode128($start = NULL) { // public
BCGBarcode1D::BCGBarcode1D();
/* CODE 128 A */
$this->keysA = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_';
for($i = 0; $i < 32; $i++) {
$this->keysA .= chr($i);
}
/* CODE 128 B */
$this->keysB = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'.chr(127);
/* CODE 128 C */
$this->keysC = '0123456789';
$this->code = array(
'101111', /* 00 */
'111011', /* 01 */
'111110', /* 02 */
'010112', /* 03 */
'010211', /* 04 */
'020111', /* 05 */
'011102', /* 06 */
'011201', /* 07 */
'021101', /* 08 */
'110102', /* 09 */
'110201', /* 10 */
'120101', /* 11 */
'001121', /* 12 */
'011021', /* 13 */
'011120', /* 14 */
'002111', /* 15 */
'012011', /* 16 */
'012110', /* 17 */
'112100', /* 18 */
'110021', /* 19 */
'110120', /* 20 */
'102101', /* 21 */
'112001', /* 22 */
'201020', /* 23 */
'200111', /* 24 */
'210011', /* 25 */
'210110', /* 26 */
'201101', /* 27 */
'211001', /* 28 */
'211100', /* 29 */
'101012', /* 30 */
'101210', /* 31 */
'121010', /* 32 */
'000212', /* 33 */
'020012', /* 34 */
'020210', /* 35 */
'001202', /* 36 */
'021002', /* 37 */
'021200', /* 38 */
'100202', /* 39 */
'120002', /* 40 */
'120200', /* 41 */
'001022', /* 42 */
'001220', /* 43 */
'021020', /* 44 */
'002012', /* 45 */
'002210', /* 46 */
'022010', /* 47 */
'202010', /* 48 */
'100220', /* 49 */
'120020', /* 50 */
'102002', /* 51 */
'102200', /* 52 */
'102020', /* 53 */
'200012', /* 54 */
'200210', /* 55 */
'220010', /* 56 */
'201002', /* 57 */
'201200', /* 58 */
'221000', /* 59 */
'203000', /* 60 */
'110300', /* 61 */
'320000', /* 62 */
'000113', /* 63 */
'000311', /* 64 */
'010013', /* 65 */
'010310', /* 66 */
'030011', /* 67 */
'030110', /* 68 */
'001103', /* 69 */
'001301', /* 70 */
'011003', /* 71 */
'011300', /* 72 */
'031001', /* 73 */
'031100', /* 74 */
'130100', /* 75 */
'110003', /* 76 */
'302000', /* 77 */
'130001', /* 78 */
'023000', /* 79 */
'000131', /* 80 */
'010031', /* 81 */
'010130', /* 82 */
'003101', /* 83 */
'013001', /* 84 */
'013100', /* 85 */
'300101', /* 86 */
'310001', /* 87 */
'310100', /* 88 */
'101030', /* 89 */
'103010', /* 90 */
'301010', /* 91 */
'000032', /* 92 */
'000230', /* 93 */
'020030', /* 94 */
'003002', /* 95 */
'003200', /* 96 */
'300002', /* 97 */
'300200', /* 98 */
'002030', /* 99 */
'003020', /* 100*/
'200030', /* 101*/
'300020', /* 102*/
'100301', /* 103*/
'100103', /* 104*/
'100121', /* 105*/
'122000' /*STOP*/
);
$this->errorText = '';
$this->setStart($start);
$this->setTilde(true);
// Latches and Shifts
$this->latch = array(
array(null, $this->KEYA_CODEB, $this->KEYA_CODEC),
array($this->KEYB_CODEA, null, $this->KEYB_CODEC),
array($this->KEYC_CODEA, $this->KEYC_CODEB, null)
);
$this->shift = array(
array(null, $this->KEYA_SHIFT),
array($this->KEYB_SHIFT, null)
);
$this->fnc = array(
array($this->KEYA_FNC1, $this->KEYA_FNC2, $this->KEYA_FNC3, $this->KEYA_FNC4),
array($this->KEYB_FNC1, $this->KEYB_FNC2, $this->KEYB_FNC3, $this->KEYB_FNC4),
array($this->KEYC_FNC1, null, null, null)
);
// Method available
$this->METHOD = array(CODE128_A => 'A', CODE128_B => 'B', CODE128_C => 'C');
}
/**
* Specifies the start code. Can be 'A', 'B', 'C' or NULL
* - Table A: Capitals + ASCII 0-31 + punct
* - Table B: Capitals + LowerCase + punct
* - Table C: Numbers
*
* If NULL is specified, the table selection is automatically made.
* The default is NULL.
*
* @param string $table
*/
function setStart($table) {
if($table !== 'A' && $table !== 'B' && $table !== 'C' && $table !== NULL) $table = NULL;
$this->starting_text = $table;
}
/**
* Accepts tilde to be process as a special character.
* If true, you can do this:
* - ~~ : to make ONE tilde
* - ~Fx : to insert FCNx. x is equal from 1 to 4.
*
* @param boolean $accept
*/
function setTilde($accept) {
$this->tilde = (bool)$accept;
}
/**
* Saves Text
*
* @param string $text
*/
function parse($text) {
$this->setStartFromText($text);
$this->errorText = ''; // Reset Error
$this->text = '';
$seq = '';
$currentMode = $this->starting_text;
// Here, we format correctly what the user gives.
if(!is_array($text)) {
$seq = $this->getSequence($text, $currentMode);
$this->text = $text;
} else {
// This loop checks for UnknownText AND raises an error if a character is not allowed in a table
reset($text);
while(list($key1, $val1) = each($text)) { // We take each value
if(!is_array($val1)) { // This is not a table
if(is_string($val1)) { // If it's a string, parse as unknown
$seq .= $this->getSequence($val1, $currentMode);
$this->text .= $val1;
} else {
// it's the case of "array(ENCODING, 'text')"
// We got ENCODING in $val1, calling 'each' again will get 'text' in $val2
list($key2, $val2) = each($text);
$seq .= $this->{'setParse' . $this->METHOD[$val1]}($val2, $currentMode);
$this->text .= $val2;
}
} else { // The method is specified
// $val1[0] = ENCODING
// $val1[1] = 'text'
$value = isset($val1[1]) ? $val1[1] : ''; // If data available
$seq .= $this->{'setParse' . $this->METHOD[$val1[0]]}($value, $currentMode);
$this->text .= $value;
}
if($this->errorText) {
break;
}
}
}
if($seq !== '') {
$bitstream = $this->createBinaryStream($this->text, $seq);
$this->setData($bitstream);
}
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
if(!empty($this->errorText)) {
$this->drawError($im, $this->errorText);
} else {
$c = count($this->data);
if($c === 0) {
$this->drawError($im, 'No text has been entered.');
} else {
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->data[$i], true);
}
$this->drawChar($im, '1', true);
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
// Contains start + text + checksum + stop
$textlength = count($this->data) * 11 * $this->scale;
$endlength = 2 * $this->scale; // + final bar
return array($p[0] + $textlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Checksum
// First Char (START)
// + Starting with the first data character following the start character,
// take the value of the character (between 0 and 102, inclusive) multiply
// it by its character position (1) and add that to the running checksum.
// Modulated 103
$this->checksumValue = $this->indcheck[0];
$c = count($this->indcheck);
for($i = 1; $i < $c; $i++) {
$this->checksumValue += $this->indcheck[$i] * $i;
}
$this->checksumValue = $this->checksumValue % 103;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
/**
* Specifies the starting_text table if none has been specified earlier.
*
* @param string $text
*/
function setStartFromText($text) {
if($this->starting_text === NULL) {
// If we have a forced table at the start, we get that one...
if(is_array($text)) {
if(is_array($text[0])) {
// Code like array(array(ENCODING, ''))
$this->starting_text = $this->METHOD[$text[0][0]];
return;
} else {
if(is_string($text[0])) {
// Code like array('test') (Automatic text)
$text = $text[0];
} else {
// Code like array(ENCODING, '')
$this->starting_text = $this->METHOD[$text[0]];
return;
}
}
}
// At this point, we had an "automatic" table selection...
// If we can get at least 4 numbers, go in C; otherwise go in B.
$tmp = preg_quote($this->keysC, '/');
if(strlen($text) >= 4 && preg_match('/[' . $tmp . ']/', substr($text, 0, 4))) {
$this->starting_text = 'C';
} else {
if(strpos($this->keysB, $text[0])) {
$this->starting_text = 'B';
} else {
$this->starting_text = 'A';
}
}
}
}
/**
* Extracts the ~ value from the $text at the $pos.
* If the tilde is not ~~, ~F1, ~F2, ~F3, ~F4; an error is raised.
*
* @param string $text
* @param int $pos
* @return string
*/
function extractTilde($text, $pos) {
if($text[$pos] === '~') {
if(isset($text[$pos + 1])) {
// Do we have a tilde?
if($text[$pos + 1] === '~') {
return '~~';
} elseif($text[$pos + 1] === 'F') {
// Do we have a number after?
if(isset($text[$pos + 2])) {
$v = intval($text[$pos + 2]);
if($v >= 1 && $v <= 4) {
return '~F' . $v;
} else {
$this->errorText = 'Bad ~F. You must provide a number from 1 to 4.';
return '';
}
} else {
$this->errorText = 'Bad ~F. You must provide a number from 1 to 4.';
return '';
}
} else {
// Wrong code
$this->errorText = 'Wrong code after the ~.';
return '';
}
} else {
// Wrong code
$this->errorText = 'Wrong code after the ~.';
return '';
}
} else {
// Can't happen
$this->errorText = 'There is no ~ at this location';
return '';
}
}
/**
* Gets the "dotted" sequence for the $text based on the $currentMode.
* There is also a check if we use the special tilde ~
*
* @param string $text
* @param string $currentMode
* @return string
*/
function getSequenceParsed($text, $currentMode) {
if($this->tilde) {
$sequence = '';
$previousPos = 0;
while(($pos = strpos($text, '~', $previousPos)) !== false) {
$tildeData = $this->extractTilde($text, $pos);
if($tildeData === '') {
// Something bad happened in extractTilde(). The errorText is already populated.
return '';
}
$simpleTilde = ($tildeData === '~~');
if($simpleTilde && $currentMode !== 'B') {
$this->errorText = 'The Table ' . $currentMode . ' doesn\'t contain the character ~.';
return '';
}
// At this point, we know we have ~Fx
if($tildeData !== '~F1' && $currentMode === 'C') {
// The mode C doesn't support ~F2, ~F3, ~F4
$this->errorText = 'The Table C doesn\'t contain the function ' . $tildeData . '.';
return '';
}
$length = $pos - $previousPos;
if($currentMode === 'C') {
if($length % 2 === 1) {
$this->errorText = 'The text "'.$text.'" must have an even number of character to be encoded in Table C.';
return '';
}
}
$sequence .= str_repeat('.', $length);
$sequence .= '.';
$sequence .= (!$simpleTilde) ? 'F' : '';
$previousPos = $pos + strlen($tildeData);
}
// Flushing
$length = strlen($text) - $previousPos;
if($currentMode === 'C') {
if($length % 2 === 1) {
$this->errorText = 'The text "'.$text.'" must have an even number of character to be encoded in Table C.';
return '';
}
}
$sequence .= str_repeat('.', $length);
return $sequence;
} else {
return str_repeat('.', strlen($text));
}
}
/**
* Parses the text and returns the appropriate sequence for the Table A.
*
* @param string $text
* @param string $currentMode
* @return string
*/
function setParseA($text, &$currentMode) {
$tmp = preg_quote($this->keysA, '/');
// If we accept the ~ for special character, we must allow it.
if($this->tilde) {
$tmp .= '~';
}
$match = array();
if(preg_match('/[^' . $tmp . ']/', $text, $match) === 1) {
// We found something not allowed
$this->errorText = 'The text "' . $text . '" can\'t be parsed with the Table A. The character "' . $match[0] . '" is not allowed.';
return '';
} else {
$latch = ($currentMode === 'A') ? '' : '0';
$currentMode = 'A';
return $latch . $this->getSequenceParsed($text, $currentMode);
}
}
/**
* Parses the text and returns the appropriate sequence for the Table B.
*
* @param string $text
* @param string $currentMode
* @return string
*/
function setParseB($text, &$currentMode) {
$tmp = preg_quote($this->keysB, '/');
$match = array();
if(preg_match('/[^' . $tmp . ']/', $text, $match) === 1) {
// We found something not allowed
$this->errorText = 'The text "'.$text.'" can\'t be parsed with the Table B. The character "' . $match[0] . '" is not allowed.';
return '';
} else {
$latch = ($currentMode === 'B') ? '' : '1';
$currentMode = 'B';
return $latch . $this->getSequenceParsed($text, $currentMode);
}
}
/**
* Parses the text and returns the appropriate sequence for the Table C.
*
* @param string $text
* @param string $currentMode
* @return string
*/
function setParseC($text, &$currentMode) {
$tmp = preg_quote($this->keysC, '/');
// If we accept the ~ for special character, we must allow it.
if($this->tilde) {
$tmp .= '~F';
}
$match = array();
if(preg_match('/[^' . $tmp . ']/', $text, $match) === 1) {
// We found something not allowed
$this->errorText = 'The text "'.$text.'" can\'t be parsed with the Table C. The character "' . $match[0] . '" is not allowed.';
return '';
} else {
$latch = ($currentMode === 'C') ? '' : '2';
$currentMode = 'C';
return $latch . $this->getSequenceParsed($text, $currentMode);
}
}
/**
* Depending on the $text, it will return the correct
* sequence to encode the text.
*
* @param string $text
* @param string $starting_text
* @return string
*/
function getSequence(&$text, &$starting_text) {
$e = 10000;
$latLen = array(
array(0, 1, 1),
array(1, 0, 1),
array(1, 1, 0)
);
$shftLen = array(
array($e, 1, $e),
array(1, $e, $e),
array($e, $e, $e)
);
$charSiz = array(2, 2, 1);
$startA = $e;
$startB = $e;
$startC = $e;
if($starting_text === 'A') $startA = 0;
if($starting_text === 'B') $startB = 0;
if($starting_text === 'C') $startC = 0;
$curLen = array($startA, $startB, $startC);
$curSeq = array(null, null, null);
$nextNumber = false;
$x = 0;
$xLen = strlen($text);
for($x = 0; $x < $xLen; $x++) {
$input = $text[$x];
// 1.
for($i = 0; $i < 3; $i++) {
for($j = 0; $j < 3; $j++) {
if(($curLen[$i] + $latLen[$i][$j]) < $curLen[$j]) {
$curLen[$j] = $curLen[$i] + $latLen[$i][$j];
$curSeq[$j] = $curSeq[$i] . $j;
}
}
}
// 2.
$nxtLen = array($e, $e, $e);
$nxtSeq = array();
// 3.
$flag = false;
$posArray = array();
// Special case, we do have a tilde and we process them
if($this->tilde && $input === '~') {
$tildeData = $this->extractTilde($text, $x);
if($tildeData === '') {
// Something bad happened in extractTilde(). The errorText is already populated.
return '';
} elseif($tildeData === '~~') {
// We simply skip a tilde
$posArray[] = 1;
$x++;
} elseif(substr($tildeData, 0, 2) === '~F') {
$v = intval($tildeData[2]);
$posArray[] = 0;
$posArray[] = 1;
if($v === 1) {
$posArray[] = 2;
}
$x += 2;
$flag = true;
}
} else {
$pos = strpos($this->keysA, $input);
if($pos !== false) {
$posArray[] = 0;
}
$pos = strpos($this->keysB, $input);
if($pos !== false) {
$posArray[] = 1;
}
$pos = strpos($this->keysC, $input);
// Do we have the next char a number?? OR a ~F1
if($nextNumber || ($pos !== false && isset($text[$x + 1]) && strpos($this->keysC, $text[$x + 1]) !== false)) {
$nextNumber = !$nextNumber;
$posArray[] = 2;
}
}
$c = count($posArray);
for($i = 0; $i < $c; $i++) {
if(($curLen[$posArray[$i]] + $charSiz[$posArray[$i]]) < $nxtLen[$posArray[$i]]) {
$nxtLen[$posArray[$i]] = $curLen[$posArray[$i]] + $charSiz[$posArray[$i]];
$nxtSeq[$posArray[$i]] = $curSeq[$posArray[$i]] . '.';
}
for($j = 0; $j < 2; $j++) {
if($j === $posArray[$i]) continue;
if(($curLen[$j] + $shftLen[$j][$posArray[$i]] + $charSiz[$posArray[$i]]) < $nxtLen[$j]) {
$nxtLen[$j] = $curLen[$j] + $shftLen[$j][$posArray[$i]] + $charSiz[$posArray[$i]];
$nxtSeq[$j] = $curSeq[$j] . chr($posArray[$i] + 65) . '.';
}
}
}
if($c === 0) {
// We found an unsuported character
$this->errorText = 'Character ' . $input . ' not supported.';
return '';
}
if($flag) {
for($i = 0; $i < 5; $i++) {
if(isset($nxtSeq[$i])) {
$nxtSeq[$i] .= 'F';
}
}
}
// 4.
for($i = 0; $i < 3; $i++) {
$curLen[$i] = $nxtLen[$i];
if(isset($nxtSeq[$i])) {
$curSeq[$i] = $nxtSeq[$i];
}
}
}
// Every curLen under $e are possible but we take the smallest !
$m = $e;
$k = -1;
for($i = 0; $i < 3; $i++) {
if($curLen[$i] < $m) {
$k = $i;
$m = $curLen[$i];
}
}
if($k === -1) {
return '';
}
$starting_text = chr($k + 65);
return $curSeq[$k];
}
/**
* Depending on the sequence $seq given (returned from getSequence()),
* this method will return the code stream in an array. Each char will be a
* string of bit based on the Code 128.
*
* Each letter from the sequence represents bits.
*
* 0 to 2 are latches
* A to B are Shift + Letter
* . is a char in the current encoding
*
* @param string $text
* @param string $seq
* @return string[][]
*/
function createBinaryStream($text, $seq) {
$c = strlen($seq);
$data = array(); // code stream
$indcheck = array(); // index for checksum
$currentEncoding = 0;
if($this->starting_text === 'A') {
$currentEncoding = 0;
$indcheck[] = $this->KEY_STARTA;
} elseif($this->starting_text === 'B') {
$currentEncoding = 1;
$indcheck[] = $this->KEY_STARTB;
} elseif($this->starting_text === 'C') {
$currentEncoding = 2;
$indcheck[] = $this->KEY_STARTC;
}
$data[] = $this->code[103 + $currentEncoding];
$temporaryEncoding = -1;
for($i = 0, $counter = 0; $i < $c; $i++) {
$input = $seq[$i];
$inputI = intval($input);
if($input === '.') {
$this->encodeChar($data, $currentEncoding, $seq, $text, $i, $counter, $indcheck);
if($temporaryEncoding !== -1) {
$currentEncoding = $temporaryEncoding;
$temporaryEncoding = -1;
}
} elseif($input >= 'A' && $input <= 'B') {
// We shift
$encoding = ord($input) - 65;
$shift = $this->shift[$currentEncoding][$encoding];
$indcheck[] = $shift;
$data[] = $this->code[$shift];
if($temporaryEncoding === -1) {
$temporaryEncoding = $currentEncoding;
}
$currentEncoding = $encoding;
} elseif($inputI >= 0 && $inputI < 3) {
$temporaryEncoding = -1;
// We latch
$latch = $this->latch[$currentEncoding][$inputI];
if($latch !== NULL) {
$indcheck[] = $latch;
$data[] = $this->code[$latch];
$currentEncoding = $inputI;
}
}
}
return array($indcheck, $data);
}
function encodeChar(&$data, $encoding, $seq, $text, &$i, &$counter, &$indcheck) {
if(isset($seq[$i + 1]) && $seq[$i + 1] === 'F') {
// We have a flag !!
if($text[$counter + 1] === 'F') {
$number = $text[$counter + 2];
$fnc = $this->fnc[$encoding][$number - 1];
$indcheck[] = $fnc;
$data[] = $this->code[$fnc];
// Skip F + number
$counter += 2;
} else {
// Not supposed
}
$i++;
} else {
if($encoding === 2) {
// We take 2 numbers in the same time
$code = (int)substr($text, $counter, 2);
$indcheck[] = $code;
$data[] = $this->code[$code];
$counter++;
$i++;
} else {
$keys = ($encoding === 0) ? $this->keysA : $this->keysB;
$pos = strpos($keys, $text[$counter]);
$indcheck[] = $pos;
$data[] = $this->code[$pos];
}
}
$counter++;
}
/**
* Saves data into the classes.
*
* This method will save data, calculate real column number
* (if -1 was selected), the real error level (if -1 was
* selected)... It will add Padding to the end and generate
* the error codes.
*
* @param array $data
*/
function setData($data) {
$this->indcheck = $data[0];
$this->data = $data[1];
$this->calculateChecksum();
$this->data[] = $this->code[$this->checksumValue];
$this->data[] = $this->code[$this->KEY_STOP];
}
};
?>

View File

@@ -0,0 +1,183 @@
<?php
/**
* BCGcode39.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - Code 39
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 30 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* v1.01 7 jul 2004 Jean-Sebastien Goupil Correction + Sign
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGcode39.barcode.php,v 1.8 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.10
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGcode39 extends BCGBarcode1D {
var $starting, $ending;
var $checksum;
/**
* Constructor
*/
function BCGcode39() { // public
BCGBarcode1D::BCGBarcode1D();
$this->starting = $this->ending = 43;
$this->keys = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','-','.',' ','$','/','+','%','*');
$this->code = array( // 0 added to add an extra space
'0001101000', /* 0 */
'1001000010', /* 1 */
'0011000010', /* 2 */
'1011000000', /* 3 */
'0001100010', /* 4 */
'1001100000', /* 5 */
'0011100000', /* 6 */
'0001001010', /* 7 */
'1001001000', /* 8 */
'0011001000', /* 9 */
'1000010010', /* A */
'0010010010', /* B */
'1010010000', /* C */
'0000110010', /* D */
'1000110000', /* E */
'0010110000', /* F */
'0000011010', /* G */
'1000011000', /* H */
'0010011000', /* I */
'0000111000', /* J */
'1000000110', /* K */
'0010000110', /* L */
'1010000100', /* M */
'0000100110', /* N */
'1000100100', /* O */
'0010100100', /* P */
'0000001110', /* Q */
'1000001100', /* R */
'0010001100', /* S */
'0000101100', /* T */
'1100000010', /* U */
'0110000010', /* V */
'1110000000', /* W */
'0100100010', /* X */
'1100100000', /* Y */
'0110100000', /* Z */
'0100001010', /* - */
'1100001000', /* . */
'0110001000', /* */
'0101010000', /* $ */
'0101000100', /* / */
'0100010100', /* + */
'0001010100', /* % */
'0100101000' /* * */
);
$this->setChecksum(false);
}
function setChecksum($checksum) {
$this->checksum = (bool)$checksum;
}
/**
* Saves Text
*
* @param string $text
*/
function parse($text) {
BCGBarcode1D::parse(strtoupper($text)); // Only Capital Letters are Allowed
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for ($i = 0; $i < $c; $i++) {
if (array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if ($error_stop === false) {
// The * is not allowed
if (strpos($this->text, '*') !== false) {
$this->drawError($im, 'Char \'*\' not allowed.');
$error_stop = true;
}
if ($error_stop === false) {
// Starting *
$this->drawChar($im, $this->code[$this->starting], true);
// Chars
for ($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->findCode($this->text[$i]), true);
}
// Checksum (rarely used)
if ($this->checksum === true) {
$this->calculateChecksum();
$this->drawChar($im, $this->code[$this->checksumValue % 43], true);
}
// Ending *
$this->drawChar($im, $this->code[$this->ending], true);
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$textlength = 13 * strlen($this->text) * $this->scale;
$startlength = 13 * $this->scale;
$checksumlength = 0;
if ($this->checksum === true) {
$checksumlength = 13 * $this->scale;
}
$endlength = 13 * $this->scale;
return array($p[0] + $startlength + $textlength + $checksumlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
$this->checksumValue = 0;
$c = strlen($this->text);
for ($i = 0; $i < $c; $i++) {
$this->checksumValue += $this->findIndex($this->text[$i]);
}
$this->checksumValue = $this->checksumValue % 43;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if ($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if ($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
};
?>

View File

@@ -0,0 +1,203 @@
<?php
/**
* BCGcode39extended.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - Code 39 Extended
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
*--------------------------------------------------------------------
* $Id: BCGcode39extended.barcode.php,v 1.3 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.3
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGcode39.barcode.php');
class BCGcode39extended extends BCGcode39 {
var $EXTENDED_1 = 39; // const
var $EXTENDED_2 = 40; // const
var $EXTENDED_3 = 41; // const
var $EXTENDED_4 = 42; // const
var $errorText;
var $indcheck, $data;
/**
* Constructor
*/
function BCGcode39extended() { // public
BCGcode39::BCGcode39();
// We just put parenthesis around special characters.
$this->keys[$this->EXTENDED_1] = '($)';
$this->keys[$this->EXTENDED_2] = '(/)';
$this->keys[$this->EXTENDED_3] = '(+)';
$this->keys[$this->EXTENDED_4] = '(%)';
$this->errorText = '';
}
/**
* Saves Text
*
* @param string $text
*/
function parse($text) {
$this->text = $text;
$data = array();
$indcheck = array();
$this->errorText = ''; // Reset Error
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
$pos = array_search($this->text[$i], $this->keys);
if($pos === false) {
// Search in extended?
$extended = $this->getExtendedVersion($this->text[$i]);
if($extended === false) {
$this->errorText .= 'Char \'' . $this->text[$i] . '\' not allowed.'."\n";
} else {
$extc = strlen($extended);
for($j = 0; $j < $extc; $j++) {
$v = $extended[$j];
if($v === '$') {
$indcheck[] = $this->EXTENDED_1;
$data[] = $this->code[$this->EXTENDED_1];
} elseif($v === '%') {
$indcheck[] = $this->EXTENDED_2;
$data[] = $this->code[$this->EXTENDED_2];
} elseif($v === '/') {
$indcheck[] = $this->EXTENDED_3;
$data[] = $this->code[$this->EXTENDED_3];
} elseif($v === '+') {
$indcheck[] = $this->EXTENDED_4;
$data[] = $this->code[$this->EXTENDED_4];
} else {
$pos2 = array_search($v, $this->keys);
$indcheck[] = $pos2;
$data[] = $this->code[$pos2];
}
}
}
} else {
$indcheck[] = $pos;
$data[] = $this->code[$pos];
}
}
$this->setData(array($indcheck, $data));
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
if(!empty($this->errorText)) {
$error = explode("\n", trim($this->errorText));
$c = count($error);
for($i = 0; $i < $c; $i++) {
$this->drawError($im, $error[$i]);
}
} else {
$c = count($this->data);
if($c === 0) {
$this->drawError($im, 'No text has been entered.');
} else {
// Starting *
$this->drawChar($im, $this->code[$this->starting], true);
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->data[$i], true);
}
// Checksum (rarely used)
if ($this->checksum === true) {
$this->drawChar($im, $this->code[$this->checksumValue % 43], true);
}
// Ending *
$this->drawChar($im, $this->code[$this->ending], true);
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$textlength = 13 * count($this->data) * $this->scale;
$startlength = 13 * $this->scale;
$checksumlength = 0;
if ($this->checksum === true) {
$checksumlength = 13 * $this->scale;
}
$endlength = 13 * $this->scale;
return array($p[0] + $startlength + $textlength + $checksumlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
$this->checksumValue = 0;
$c = count($this->indcheck);
for ($i = 0; $i < $c; $i++) {
$this->checksumValue += $this->indcheck[$i];
}
$this->checksumValue = $this->checksumValue % 43;
}
/**
* Saves data into the classes.
*
* This method will save data, calculate real column number
* (if -1 was selected), the real error level (if -1 was
* selected)... It will add Padding to the end and generate
* the error codes.
*
* @param array $data
*/
function setData($data) {
$this->indcheck = $data[0];
$this->data = $data[1];
$this->calculateChecksum();
}
function getExtendedVersion($char) {
$o = ord($char);
if($o === 0)
return '%U';
elseif($o >= 1 && $o <= 26)
return '$' . chr($o + 64);
elseif(($o >= 33 && $o <= 44) || $o === 47 || $o === 48)
return '/' . chr($o + 32);
elseif($o >= 97 && $o <= 122)
return '+' . chr($o - 32);
elseif($o >= 27 && $o <= 31)
return '%' . chr($o + 38);
elseif($o >= 59 && $o <= 63)
return '%' . chr($o + 11);
elseif($o >= 91 && $o <= 95)
return '%' . chr($o - 16);
elseif($o >= 123 && $o <= 127)
return '%' . chr($o - 43);
elseif($o === 64)
return '%V';
elseif($o === 96)
return '%W';
elseif($o > 127)
return false;
else
return $char;
}
};
?>

View File

@@ -0,0 +1,295 @@
<?php
/**
* BCGcode93.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - Code 93
*
* !! Warning !!
* If you display the checksum on the barcode, you may obtain
* some garbage since some characters are not displayable.
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 30 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGcode93.barcode.php,v 1.8 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.10
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGcode93 extends BCGBarcode1D {
var $EXTENDED_1 = 43; // const
var $EXTENDED_2 = 44; // const
var $EXTENDED_3 = 45; // const
var $EXTENDED_4 = 46; // const
var $starting, $ending;
var $indcheck, $data;
var $errorText;
/**
* Constructor
*/
function BCGcode93() { // public
BCGBarcode1D::BCGBarcode1D();
$this->starting = $this->ending = 47; /* * */
$this->keys = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','-','.',' ','$','/','+','%','($)','(%)','(/)','(+)','(*)');
$this->code = array(
'020001', /* 0 */
'000102', /* 1 */
'000201', /* 2 */
'000300', /* 3 */
'010002', /* 4 */
'010101', /* 5 */
'010200', /* 6 */
'000003', /* 7 */
'020100', /* 8 */
'030000', /* 9 */
'100002', /* A */
'100101', /* B */
'100200', /* C */
'110001', /* D */
'110100', /* E */
'120000', /* F */
'001002', /* G */
'001101', /* H */
'001200', /* I */
'011001', /* J */
'021000', /* K */
'000012', /* L */
'000111', /* M */
'000210', /* N */
'010011', /* O */
'020010', /* P */
'101001', /* Q */
'101100', /* R */
'100011', /* S */
'100110', /* T */
'110010', /* U */
'111000', /* V */
'001011', /* W */
'001110', /* X */
'011010', /* Y */
'012000', /* Z */
'010020', /* - */
'200001', /* . */
'200100', /* */
'210000', /* $ */
'001020', /* / */
'002010', /* + */
'100020', /* % */
'010110', /*($)*/
'201000', /*(%)*/
'200010', /*(/)*/
'011100', /*(+)*/
'000030' /*(*)*/
);
$this->errorText = '';
}
/**
* Saves Text
*
* @param string $text
*/
function parse($text) {
$this->text = $text;
$data = array();
$indcheck = array();
$this->errorText = ''; // Reset Error
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
$pos = array_search($this->text[$i], $this->keys);
if($pos === false) {
// Search in extended?
$extended = $this->getExtendedVersion($this->text[$i]);
if($extended === false) {
$this->errorText .= 'Char \'' . $this->text[$i] . '\' not allowed.'."\n";
} else {
$extc = strlen($extended);
for($j = 0; $j < $extc; $j++) {
$v = $extended[$j];
if($v === '$') {
$indcheck[] = $this->EXTENDED_1;
$data[] = $this->code[$this->EXTENDED_1];
} elseif($v === '%') {
$indcheck[] = $this->EXTENDED_2;
$data[] = $this->code[$this->EXTENDED_2];
} elseif($v === '/') {
$indcheck[] = $this->EXTENDED_3;
$data[] = $this->code[$this->EXTENDED_3];
} elseif($v === '+') {
$indcheck[] = $this->EXTENDED_4;
$data[] = $this->code[$this->EXTENDED_4];
} else {
$pos2 = array_search($v, $this->keys);
$indcheck[] = $pos2;
$data[] = $this->code[$pos2];
}
}
}
} else {
$indcheck[] = $pos;
$data[] = $this->code[$pos];
}
}
$this->setData(array($indcheck, $data));
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
if(!empty($this->errorText)) {
$error = explode("\n", trim($this->errorText));
$c = count($error);
for($i = 0; $i < $c; $i++) {
$this->drawError($im, $error[$i]);
}
} else {
$c = count($this->data);
if($c === 0) {
$this->drawError($im, 'No text has been entered.');
} else {
// Starting *
$this->drawChar($im, $this->code[$this->starting], true);
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->data[$i], true);
}
// Checksum
$c = count($this->checksumValue);
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->code[$this->checksumValue[$i]], true);
}
// Ending *
$this->drawChar($im, $this->code[$this->ending], true);
// Draw a Final Bar
$this->drawChar($im, '0', true);
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$startlength = 9 * $this->scale;
$textlength = 9 * count($this->data) * $this->scale;
$checksumlength = 2 * 9 * $this->scale;
$endlength = 9 * $this->scale + $this->scale; // + final bar
return array($p[0] + $startlength + $textlength + $checksumlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Checksum
// First CheckSUM "C"
// The "C" checksum character is the modulo 47 remainder of the sum of the weighted
// value of the data characters. The weighting value starts at "1" for the right-most
// data character, 2 for the second to last, 3 for the third-to-last, and so on up to 20.
// After 20, the sequence wraps around back to 1.
// Second CheckSUM "K"
// Same as CheckSUM "C" but we count the CheckSum "C" at the end
// After 15, the sequence wraps around back to 1.
$sequence_multiplier = array(20, 15);
$this->checksumValue = array();
$indcheck = $this->indcheck;
for($z = 0; $z < 2; $z++) {
$checksum = 0;
for($i = count($indcheck), $j = 0; $i > 0; $i--, $j++) {
$multiplier = $i % $sequence_multiplier[$z];
if($multiplier === 0) {
$multiplier = $sequence_multiplier[$z];
}
$checksum += $indcheck[$j] * $multiplier;
}
$this->checksumValue[$z] = $checksum % 47;
$indcheck[] = $this->checksumValue[$z];
}
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
$ret = '';
$c = count($this->checksumValue);
for($i = 0; $i < $c; $i++) {
$ret .= $this->keys[$this->checksumValue[$i]];
}
return $ret;
}
return false;
}
/**
* Saves data into the classes.
*
* This method will save data, calculate real column number
* (if -1 was selected), the real error level (if -1 was
* selected)... It will add Padding to the end and generate
* the error codes.
*
* @param array $data
*/
function setData($data) {
$this->indcheck = $data[0];
$this->data = $data[1];
$this->calculateChecksum();
}
function getExtendedVersion($char) {
$o = ord($char);
if($o === 0)
return '%U';
elseif($o >= 1 && $o <= 26)
return '$' . chr($o + 64);
elseif(($o >= 33 && $o <= 44) || $o === 47 || $o === 48)
return '/' . chr($o + 32);
elseif($o >= 97 && $o <= 122)
return '+' . chr($o - 32);
elseif($o >= 27 && $o <= 31)
return '%' . chr($o + 38);
elseif($o >= 59 && $o <= 63)
return '%' . chr($o + 11);
elseif($o >= 91 && $o <= 95)
return '%' . chr($o - 16);
elseif($o >= 123 && $o <= 127)
return '%' . chr($o - 43);
elseif($o === 64)
return '%V';
elseif($o === 96)
return '%W';
elseif($o > 127)
return false;
else
return $char;
}
};
?>

View File

@@ -0,0 +1,342 @@
<?php
/**
* BCGean13.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - EAN-13
*
* EAN-13 contains
* - 2 system digits (1 not displayed but coded with parity)
* - 5 manufacturer code digits
* - 5 product digits
* - 1 checksum digit
*
* The checksum is always displayed.
*
*--------------------------------------------------------------------
* Revision History
* v2.0.1 8 mar 2009 Jean-Sébastien Goupil Fix padding for the barcode
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.3.0 13 apr 2007 Jean-Sébastien Goupil Move ISBN implementation to isbn.php
* v1.2.3pl1 11 mar 2006 Jean-Sébastien Goupil Correct getMaxWidth if ISBN
* v1.2.3 6 feb 2006 Jean-Sébastien Goupil Fix label position + Using correctly static method
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.2 23 jul 2005 Jean-Sébastien Goupil Enhance rapidity
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGean13.barcode.php,v 1.14 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.13
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGean13 extends BCGBarcode1D {
var $codeParity = array();
/**
* Constructor
*/
function BCGean13() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
// Left-Hand Odd Parity starting with a space
// Left-Hand Even Parity is the inverse (0=0012) starting with a space
// Right-Hand is the same of Left-Hand starting with a bar
$this->code = array(
'2100', /* 0 */
'1110', /* 1 */
'1011', /* 2 */
'0300', /* 3 */
'0021', /* 4 */
'0120', /* 5 */
'0003', /* 6 */
'0201', /* 7 */
'0102', /* 8 */
'2001' /* 9 */
);
// Parity, 0=Odd, 1=Even for manufacturer code. Depending on 1st System Digit
$this->codeParity = array(
array(0,0,0,0,0), /* 0 */
array(0,1,0,1,1), /* 1 */
array(0,1,1,0,1), /* 2 */
array(0,1,1,1,0), /* 3 */
array(1,0,0,1,1), /* 4 */
array(1,1,0,0,1), /* 5 */
array(1,1,1,0,0), /* 6 */
array(1,0,1,0,1), /* 7 */
array(1,0,1,1,0), /* 8 */
array(1,1,0,1,0) /* 9 */
);
}
function parse($text) {
BCGBarcode1D::parse($text);
$this->setLabelOffset();
}
function setFont($font) {
BCGBarcode1D::setFont($font);
$this->setLabelOffset();
}
function setLabel($label) {
BCGBarcode1D::setLabel($label);
$this->setLabelOffset();
}
function setOffsetX($offsetX) {
BCGBarcode1D::setOffsetX($offsetX);
$this->setLabelOffset();
}
function setScale($scale) {
BCGBarcode1D::setScale($scale);
$this->setLabelOffset();
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
if($this->isCharsAllowed($im)) {
if($this->isLengthCorrect($im)) {
$this->drawBars($im);
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$startlength = 3 * $this->scale;
$centerlength = 5 * $this->scale;
$textlength = 12 * 7 * $this->scale;
$endlength = 3 * $this->scale;
return array($p[0] + $startlength + $centerlength + $textlength + $endlength, $p[1]);
}
function setLabelOffset() {
$label = $this->getLabel();
if(!empty($label)) {
if(is_a($this->textfont, 'BCGFont')) {
$f = $this->textfont; // clone
$f->setText(substr($label, 0, 1));
$val = ($f->getWidth() + 5) / $this->scale;
if($val > $this->offsetX) {
$this->offsetX = $val;
}
} elseif($this->textfont !== 0) {
$val = (imagefontwidth($this->textfont) + 2) / $this->scale;
if($val > $this->offsetX) {
$this->offsetX = $val;
}
}
}
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Calculating Checksum
// Consider the right-most digit of the message to be in an "odd" position,
// and assign odd/even to each character moving from right to left
// Odd Position = 3, Even Position = 1
// Multiply it by the number
// Add all of that and do 10-(?mod10)
$odd = true;
$this->checksumValue = 0;
$c = strlen($this->text);
for($i = $c; $i > 0; $i--) {
if($odd === true) {
$multiplier = 3;
$odd = false;
} else {
$multiplier = 1;
$odd = true;
}
if(!isset($this->keys[$this->text[$i - 1]])) {
return;
}
$this->checksumValue += $this->keys[$this->text[$i - 1]] * $multiplier;
}
$this->checksumValue = (10 - $this->checksumValue % 10) % 10;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
function isCharsAllowed(&$im) {
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
return false;
}
}
return true;
}
function isLengthCorrect(&$im) {
$c = strlen($this->text);
// If we have 13 chars just flush the last one
if($c === 13) {
$this->text = substr($this->text, 0, 12);
return true;
} elseif($c === 12) {
return true;
}
$this->drawError($im, 'Must provide 12 or 13 digits.');
return false;
}
function drawBars(&$im) {
// Checksum
$this->calculateChecksum();
$temp_text = $this->text . $this->keys[$this->checksumValue];
// Starting Code
$this->drawChar($im, '000', true);
// Draw Second Code
$this->drawChar($im, $this->findCode($temp_text[1]), false);
// Draw Manufacturer Code
for($i = 0; $i < 5; $i++) {
$this->drawChar($im, BCGean13::inverse($this->findCode($temp_text[$i + 2]), $this->codeParity[(int)$temp_text[0]][$i]), false);
}
// Draw Center Guard Bar
$this->drawChar($im, '00000', false);
// Draw Product Code
for($i = 7; $i < 13; $i++) {
$this->drawChar($im, $this->findCode($temp_text[$i]), true);
}
// Draw Right Guard Bar
$this->drawChar($im, '000', true);
}
/**
* Overloaded method for drawing special label
*
* @param resource $im
*/
function drawText(&$im) {
if($this->label !== $this->AUTO_LABEL) {
BCGBarcode1D::drawText($im);
} elseif($this->label !== '') {
$temp_text = $this->text . $this->keys[$this->checksumValue];
if (is_a($this->textfont, 'BCGFont')) {
$code1 = 0;
$code2 = 0;
$this->textfont->setText($temp_text);
$this->drawExtendedBars($im, $this->textfont->getHeight(), $code1, $code2);
// We need to separate the text, one on the left and one on the right and one starting
$text0 = substr($temp_text, 0, 1);
$text1 = substr($temp_text, 1, 6);
$text2 = substr($temp_text, 7, 6);
$font0 = $this->textfont; // clone
$font1 = $this->textfont; // clone
$font2 = $this->textfont; // clone
$font0->setText($text0);
$font1->setText($text1);
$font2->setText($text2);
$xPosition0 = $this->offsetX * $this->scale - $font0->getWidth() - 4; // -4 is just for beauty
$yPosition0 = $this->thickness * $this->scale + $font0->getHeight() / 2 + $this->offsetY * $this->scale;
$xPosition1 = ($this->scale * 44 - $font1->getWidth()) / 2 + $code1 * $this->scale + $this->offsetX * $this->scale;
$xPosition2 = ($this->scale * 44 - $font1->getWidth()) / 2 + $code2 * $this->scale + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $this->textfont->getHeight() + $this->SIZE_SPACING_FONT + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
$font0->draw($im, $text_color, $xPosition0, $yPosition0);
$font1->draw($im, $text_color, $xPosition1, $yPosition);
$font2->draw($im, $text_color, $xPosition2, $yPosition);
} elseif($this->textfont !== 0) {
$code1 = 0;
$code2 = 0;
$this->drawExtendedBars($im, 9, $code1, $code2);
$startPosition = 10;
$xPosition0 = $this->offsetX * $this->scale - imagefontwidth($this->textfont);
$yPosition0 = $this->thickness * $this->scale - imagefontheight($this->textfont) / 2 + $this->offsetY * $this->scale;
$xPosition1 = ($this->scale * 44 - imagefontwidth($this->textfont) * 6) / 2 + $code1 * $this->scale + $this->offsetX * $this->scale;
$xPosition2 = ($this->scale * 44 - imagefontwidth($this->textfont) * 6) / 2 + $code2 * $this->scale + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + 1 * $this->scale + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
imagechar($im, $this->textfont, $xPosition0, $yPosition0, $temp_text[0], $text_color);
imagestring($im, $this->textfont, $xPosition1, $yPosition, substr($temp_text, 1, 6), $text_color);
imagestring($im, $this->textfont, $xPosition2, $yPosition, substr($temp_text, 7, 6), $text_color);
}
}
}
function drawExtendedBars(&$im, $plus, &$code1, &$code2) {
$rememberX = $this->positionX;
$rememberH = $this->thickness;
// We increase the bars
$this->thickness = $this->thickness + ceil($plus / $this->scale);
$this->positionX = 0;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
$code1 = $this->positionX;
// Center Guard Bar
$this->positionX += 44;
$this->DrawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->DrawSingleBar($im, $this->COLOR_FG);
// Last Bars
$code2 = $this->positionX;
$this->positionX += 44;
$this->DrawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->DrawSingleBar($im, $this->COLOR_FG);
$this->positionX = $rememberX;
$this->thickness = $rememberH;
}
function inverse($text, $inverse = 1) { // static
if($inverse === 1) {
$text = strrev($text);
}
return $text;
}
};
?>

View File

@@ -0,0 +1,238 @@
<?php
/**
* BCGean8.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - EAN-8
*
* EAN-8 contains
* - 4 digits
* - 3 digits
* - 1 checksum
*
* The checksum is always displayed.
*
*--------------------------------------------------------------------
* Revision History
* v2.0.1 8 mar 2009 Jean-Sébastien Goupil Fix padding for the barcode
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3 6 feb 2006 Jean-Sébastien Goupil Fix label position
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.2 23 jul 2005 Jean-Sébastien Goupil Enhance rapidity
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGean8.barcode.php,v 1.11 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.12
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGean8 extends BCGBarcode1D {
/**
* Constructor
*/
function BCGean8() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
// Left-Hand Odd Parity starting with a space
// Right-Hand is the same of Left-Hand starting with a bar
$this->code = array(
'2100', /* 0 */
'1110', /* 1 */
'1011', /* 2 */
'0300', /* 3 */
'0021', /* 4 */
'0120', /* 5 */
'0003', /* 6 */
'0201', /* 7 */
'0102', /* 8 */
'2001' /* 9 */
);
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must contain 7 chars
if($c !== 7) {
$this->drawError($im, 'Must contain 7 chars, the 8th digit is automatically added.');
$error_stop = true;
}
if($error_stop === false) {
// Checksum
$this->calculateChecksum();
$temp_text = $this->text . $this->keys[$this->checksumValue];
// Starting Code
$this->drawChar($im, '000', true);
// Draw First 4 Chars (Left-Hand)
for($i = 0; $i < 4; $i++) {
$this->drawChar($im, $this->findCode($temp_text[$i]), false);
}
// Draw Center Guard Bar
$this->drawChar($im, '00000', false);
// Draw Last 4 Chars (Right-Hand)
for($i = 4; $i < 8; $i++) {
$this->drawChar($im, $this->findCode($temp_text[$i]), true);
}
// Draw Right Guard Bar
$this->drawChar($im, '000', true);
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$startlength = 3 * $this->scale;
$centerlength = 5 * $this->scale;
$textlength = 8 * 7 * $this->scale;
$endlength = 3 * $this->scale;
return array($p[0] + $startlength + $centerlength + $textlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Calculating Checksum
// Consider the right-most digit of the message to be in an "odd" position,
// and assign odd/even to each character moving from right to left
// Odd Position = 3, Even Position = 1
// Multiply it by the number
// Add all of that and do 10-(?mod10)
$odd = true;
$this->checksumValue = 0;
$c = strlen($this->text);
for($i = $c; $i > 0; $i--) {
if($odd === true) {
$multiplier = 3;
$odd = false;
} else {
$multiplier = 1;
$odd = true;
}
if(!isset($this->keys[$this->text[$i - 1]])) {
return;
}
$this->checksumValue += $this->keys[$this->text[$i - 1]] * $multiplier;
}
$this->checksumValue = (10 - $this->checksumValue % 10) % 10;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
/**
* Overloaded method for drawing special label
*
* @param resource $im
*/
function drawText(&$im) {
if($this->label !== $this->AUTO_LABEL) {
BCGBarcode1D::drawText($im);
} elseif($this->label !== '') {
$temp_text = $this->text . $this->keys[$this->checksumValue];
if(is_a($this->textfont, 'BCGFont')) {
$code1 = 0;
$code2 = 0;
$this->textfont->setText($temp_text);
$this->drawExtendedBars($im, $this->textfont->getHeight(), $code1, $code2);
// We need to separate the text, one on the left and one on the right
$text1 = substr($temp_text, 0, 4);
$text2 = substr($temp_text, 4, 4);
$font1 = $this->textfont; // clone
$font2 = $this->textfont; // clone
$font1->setText($text1);
$font2->setText($text2);
// The $this->res offset is to center without thinking of the white space in the guard
$xPosition1 = ($this->scale * 30 - $font1->getWidth()) / 2 + $code1 * $this->scale + $this->offsetX * $this->scale;
$xPosition2 = ($this->scale * 30 - $font2->getWidth()) / 2 + $code2 * $this->scale + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $this->textfont->getHeight() + $this->SIZE_SPACING_FONT + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
$font1->draw($im, $text_color, $xPosition1, $yPosition);
$font2->draw($im, $text_color, $xPosition2, $yPosition);
} elseif($this->textfont !== 0) {
$code1 = 0;
$code2 = 0;
$this->drawExtendedBars($im, 9, $code1, $code2);
$xPosition1 = ($this->scale * 30 - imagefontwidth($this->textfont) * 4) / 2 + $code1 * $this->scale + $this->offsetX * $this->scale;
$xPosition2 = ($this->scale * 30 - imagefontwidth($this->textfont) * 4) / 2 + $code2 * $this->scale + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + 1 * $this->scale + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
imagestring($im, $this->textfont, $xPosition1, $yPosition, substr($temp_text, 0, 4), $text_color);
imagestring($im, $this->textfont, $xPosition2, $yPosition, substr($temp_text, 4, 4), $text_color);
}
}
}
function drawExtendedBars(&$im, $plus, &$code1, &$code2) {
$rememberX = $this->positionX;
$rememberH = $this->thickness;
// We increase the bars
$this->thickness = $this->thickness + ceil($plus / $this->scale);
$this->positionX = 0;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
$code1 = $this->positionX;
// Center Guard Bar
$this->positionX += 30;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
// Last Bars
$code2 = $this->positionX;
$this->positionX += 30;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX = $rememberX;
$this->thickness = $rememberH;
}
};
?>

View File

@@ -0,0 +1,592 @@
<?php
/**
* BCGgs1128.barcode.php
*--------------------------------------------------------------------
*
* Calculate the GS1-128 based on the Code-128 encoding.
*
*--------------------------------------------------------------------
* Revision History
* V2.2.0 10 feb 2010 Kevin Gilbert, reviewed by Jean-Sébastien Goupil, new version
*--------------------------------------------------------------------
* $Id: BCGgs1128.barcode.php,v 1.1 2010/02/14 00:25:14 jsgoupil Exp $<
* PHP5-Revision: 1.1
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGcode128.barcode.php');
class BCGgs1128 extends BCGcode128 {
var $KIND_OF_DATA = 0; // const
var $MINLENGTH = 1; // const
var $MAXLENGTH = 2; // const
var $CHECKSUM = 3; // const
var $NUMERIC = 0; // const
var $ALPHA_NUMERIC = 1; // const
var $DATE_YYMMDD = 2; // const
var $ID = 0; // const
var $CONTENT = 1; // const
var $MAX_ID_FORMATED = 6; // const
var $MAX_ID_NOT_FORMATED = 4; // const
var $MAX_GS1128_CHARS = 48; // const
var $errorTextGS1128;
var $strictMode;
var $identifiersId = array();
var $identifiersContent = array();
var $identifiersAi = array();
/**
* Constructor
*
* @param char $start
*/
function BCGgs1128($start = NULL) { // public
if($start === NULL) {
$start = 'C';
}
BCGcode128::BCGcode128($start);
/* Application Identifiers (AIs) */
/*
array ( KIND_OF_DATA , MINLENGTH , MAXLENGTH , CHECKSUM )
KIND_OF_DATA: NUMERIC , ALPHA_NUMERIC or DATE_YYMMDD
CHECKSUM: bool (true / false)
*/
$this->identifiersAi = array(
'00' => array($this->NUMERIC, 18, 18, true),
'01' => array($this->NUMERIC, 14, 14, true),
'02' => array($this->NUMERIC, 14, 14, true),
'10' => array($this->ALPHA_NUMERIC, 1, 20, false),
'11' => array($this->DATE_YYMMDD, 6, 6, false),
'12' => array($this->DATE_YYMMDD, 6, 6, false),
'13' => array($this->DATE_YYMMDD, 6, 6, false),
'15' => array($this->DATE_YYMMDD, 6, 6, false),
'17' => array($this->DATE_YYMMDD, 6, 6, false),
'20' => array($this->NUMERIC, 2, 2, false),
'21' => array($this->ALPHA_NUMERIC, 1, 20, false),
'240' => array($this->ALPHA_NUMERIC, 1, 30, false),
'241' => array($this->ALPHA_NUMERIC, 1, 30, false),
'250' => array($this->ALPHA_NUMERIC, 1, 30, false),
'251' => array($this->ALPHA_NUMERIC, 1, 30, false),
'253' => array($this->NUMERIC, 14, 30, false),
'30' => array($this->NUMERIC, 1, 8, false),
'310y' => array($this->NUMERIC, 6, 6, false),
'311y' => array($this->NUMERIC, 6, 6, false),
'312y' => array($this->NUMERIC, 6, 6, false),
'313y' => array($this->NUMERIC, 6, 6, false),
'314y' => array($this->NUMERIC, 6, 6, false),
'315y' => array($this->NUMERIC, 6, 6, false),
'316y' => array($this->NUMERIC, 6, 6, false),
'320y' => array($this->NUMERIC, 6, 6, false),
'321y' => array($this->NUMERIC, 6, 6, false),
'322y' => array($this->NUMERIC, 6, 6, false),
'323y' => array($this->NUMERIC, 6, 6, false),
'324y' => array($this->NUMERIC, 6, 6, false),
'325y' => array($this->NUMERIC, 6, 6, false),
'326y' => array($this->NUMERIC, 6, 6, false),
'327y' => array($this->NUMERIC, 6, 6, false),
'328y' => array($this->NUMERIC, 6, 6, false),
'329y' => array($this->NUMERIC, 6, 6, false),
'330y' => array($this->NUMERIC, 6, 6, false),
'331y' => array($this->NUMERIC, 6, 6, false),
'332y' => array($this->NUMERIC, 6, 6, false),
'333y' => array($this->NUMERIC, 6, 6, false),
'334y' => array($this->NUMERIC, 6, 6, false),
'335y' => array($this->NUMERIC, 6, 6, false),
'336y' => array($this->NUMERIC, 6, 6, false),
'337y' => array($this->NUMERIC, 6, 6, false),
'340y' => array($this->NUMERIC, 6, 6, false),
'341y' => array($this->NUMERIC, 6, 6, false),
'342y' => array($this->NUMERIC, 6, 6, false),
'343y' => array($this->NUMERIC, 6, 6, false),
'344y' => array($this->NUMERIC, 6, 6, false),
'345y' => array($this->NUMERIC, 6, 6, false),
'346y' => array($this->NUMERIC, 6, 6, false),
'347y' => array($this->NUMERIC, 6, 6, false),
'348y' => array($this->NUMERIC, 6, 6, false),
'349y' => array($this->NUMERIC, 6, 6, false),
'350y' => array($this->NUMERIC, 6, 6, false),
'351y' => array($this->NUMERIC, 6, 6, false),
'352y' => array($this->NUMERIC, 6, 6, false),
'353y' => array($this->NUMERIC, 6, 6, false),
'354y' => array($this->NUMERIC, 6, 6, false),
'355y' => array($this->NUMERIC, 6, 6, false),
'356y' => array($this->NUMERIC, 6, 6, false),
'357y' => array($this->NUMERIC, 6, 6, false),
'360y' => array($this->NUMERIC, 6, 6, false),
'361y' => array($this->NUMERIC, 6, 6, false),
'362y' => array($this->NUMERIC, 6, 6, false),
'363y' => array($this->NUMERIC, 6, 6, false),
'364y' => array($this->NUMERIC, 6, 6, false),
'365y' => array($this->NUMERIC, 6, 6, false),
'366y' => array($this->NUMERIC, 6, 6, false),
'367y' => array($this->NUMERIC, 6, 6, false),
'368y' => array($this->NUMERIC, 6, 6, false),
'369y' => array($this->NUMERIC, 6, 6, false),
'37' => array($this->NUMERIC, 1, 8, false),
'390y' => array($this->NUMERIC, 1, 15, false),
'391y' => array($this->NUMERIC, 4, 18, false),
'392y' => array($this->NUMERIC, 1, 15, false),
'393y' => array($this->NUMERIC, 4, 18, false),
'400' => array($this->ALPHA_NUMERIC, 1, 30, false),
'401' => array($this->ALPHA_NUMERIC, 1, 30, false),
'402' => array($this->NUMERIC, 17, 17, false),
'403' => array($this->ALPHA_NUMERIC, 1, 30, false),
'410' => array($this->NUMERIC, 13, 13, true),
'411' => array($this->NUMERIC, 13, 13, true),
'412' => array($this->NUMERIC, 13, 13, true),
'413' => array($this->NUMERIC, 13, 13, true),
'414' => array($this->NUMERIC, 13, 13, true),
'415' => array($this->NUMERIC, 13, 13, true),
'420' => array($this->ALPHA_NUMERIC, 1, 20, false),
'421' => array($this->ALPHA_NUMERIC, 4, 12, false),
'422' => array($this->NUMERIC, 3, 3, false),
'8001' => array($this->NUMERIC, 14, 14, false),
'8002' => array($this->ALPHA_NUMERIC, 1, 20, false),
'8003' => array($this->ALPHA_NUMERIC, 15, 30, false),
'8004' => array($this->ALPHA_NUMERIC, 1, 30, false),
'8005' => array($this->NUMERIC, 6, 6, false),
'8006' => array($this->NUMERIC, 18, 18, false),
'8007' => array($this->ALPHA_NUMERIC, 1, 30, false),
'8018' => array($this->NUMERIC, 18, 18, false),
'8020' => array($this->ALPHA_NUMERIC, 1, 25, false),
'8100' => array($this->NUMERIC, 6, 6, false),
'8101' => array($this->NUMERIC, 10, 10, false),
'8102' => array($this->NUMERIC, 2, 2, false),
'90' => array($this->ALPHA_NUMERIC, 1, 30, false),
'91' => array($this->ALPHA_NUMERIC, 1, 30, false),
'92' => array($this->ALPHA_NUMERIC, 1, 30, false),
'93' => array($this->ALPHA_NUMERIC, 1, 30, false),
'94' => array($this->ALPHA_NUMERIC, 1, 30, false),
'95' => array($this->ALPHA_NUMERIC, 1, 30, false),
'96' => array($this->ALPHA_NUMERIC, 1, 30, false),
'97' => array($this->ALPHA_NUMERIC, 1, 30, false),
'98' => array($this->ALPHA_NUMERIC, 1, 30, false),
'99' => array($this->ALPHA_NUMERIC, 1, 30, false)
);
$this->setStrictMode(true);
$this->setTilde(true);
}
/**
* Enables or disables the strict mode
*
* @param bool strictMode
*/
function setStrictMode($strictMode) { // public
$this->strictMode = $strictMode;
}
/**
* Parses Text
*
* @param string $text
*/
function parse($text) { // public
parent::parse($this->parseGs1128($text));
$this->errorText .= $this->errorTextGS1128;
}
/**
* Formats data for gs1-128
*
* @return string
*/
function formatGs1128() { // private
$formatedText = '~F1';
$formatedLabel = '';
$c = count($this->identifiersId);
for($i = 0; $i < $c; $i++) {
if($i > 0) {
$formatedLabel .= ' ';
}
$formatedLabel .= '(' . $this->identifiersId[$i] . ')';
$formatedText .= $this->identifiersId[$i];
$formatedLabel .= $this->identifiersContent[$i];
$formatedText .= $this->identifiersContent[$i];
if(isset($this->identifiersAi[$this->identifiersId[$i]])) {
$ai_data = $this->identifiersAi[$this->identifiersId[$i]];
} elseif(isset($this->identifiersId[$i][3])) {
$identifierWithVar = substr($this->identifiersId[$i], 0, -1) . 'y';
$ai_data = isset($this->identifiersAi[$identifierWithVar]) ? $this->identifiersAi[$identifierWithVar] : NULL;
} else {
$ai_data = NULL;
}
/* We'll check if we need to add a ~F1 (<GS>) char */
/* If we use the legacy mode, we always add a ~F1 (<GS>) char between AIs */
if($ai_data !== NULL) {
if(strlen($this->identifiersContent[$i]) < $ai_data[$this->MAXLENGTH] && ($i + 1) !== $c || !$this->strictMode && ($i + 1) !== $c) {
$formatedText .= '~F1';
}
}
}
if((strlen($formatedText) - 3) > $this->MAX_GS1128_CHARS) {
$this->errorTextGS1128 = 'The barcode can\'t be bigger than ' . $this->MAX_GS1128_CHARS . ' characters.';
}
$this->label = $formatedLabel;
return $formatedText;
}
/**
* Parses the text to gs1-128
*
* @param mixed $text
* @return mixed
*/
function parseGs1128($text) { // private
/* We format correctly what the user gives */
if(is_array($text)) {
$formatArray = array();
foreach($text as $content) {
if(is_array($content)) { /* double array */
if(count($content) === 2) {
if(is_array($content[$this->ID]) || is_array($content[$this->CONTENT])) {
$this->errorTextGS1128 = 'Double arrays can\'t contain arrays.';
return false;
} else {
$formatArray[] = '(' . $content[$this->ID] . ')' . $content[$this->CONTENT];
}
} else {
$this->errorTextGS1128 = 'Double arrays must contain 2 values.';
return false;
}
} else { /* simple array */
$formatArray[] = $content;
}
}
unset($text);
$text = $formatArray;
} else { /* string */
$text = array($text);
}
$textCount = count($text);
for($cmpt = 0; $cmpt < $textCount; $cmpt++) {
/* We parse the content of the array */
if(!$this->parseContent($text[$cmpt])) {
return false;
}
}
return $this->formatGs1128();
}
/**
* Splits the id and the content for each application identifiers (AIs)
*
* @param string $text
* @param int $cmpt
*
* @return bool
*/
function parseContent($text) { // private
/* $yAlreadySet has 3 states: */
/* null: There is no variable in the ID; true: the variable is already set; false: the variable is not set yet; */
$yAlreadySet = NULL;
$realNameId = NULL;
$separatorsFound = 0;
$checksumAdded = 0;
$decimalPointRemoved = 0;
$toParse = str_replace('~F1' ,chr(29), $text);
$nbCharToParse = strlen($toParse);
$isFormated = $toParse[0] === '(' ? true : false;
$maxCharId = $isFormated ? $this->MAX_ID_FORMATED : $this->MAX_ID_NOT_FORMATED;
$id = strtolower(substr($toParse, 0, min($maxCharId, $nbCharToParse)));
$id = $isFormated ? $this->findIdFormated($id, $yAlreadySet, $realNameId) : $this->findIdNotFormated($id, $yAlreadySet, $realNameId);
if($id === false) {
return false;
}
$nbCharId = $isFormated ? strlen($id) + 2 : strlen($id);
$n = min($this->identifiersAi[$realNameId][$this->MAXLENGTH], $nbCharToParse);
$content = substr($toParse, $nbCharId, $n);
/* If we have an AI with an "y" var, we check if there is a decimal point in the next *MAXLENGTH* characters */
/* if there is one, we take an extra character */
if($yAlreadySet !== NULL) {
if(strpos($content, '.') !== false || strpos($content, ',') !== false) {
$n++;
if($n <= $nbCharToParse) {
/* We take an extra char */
$content = substr($toParse, $nbCharId, $n);
}
}
}
/* We check for separator */
$separator = strpos($content, chr(29));
if($separator !== false) {
$content = substr($content, 0, $separator);
$separatorsFound++;
}
/* We check the conformity */
if(!$this->checkConformity($content, $id, $realNameId)) {
return false;
}
/* We check the checksum */
if(!$this->checkChecksum($content, $id, $realNameId, $checksumAdded)) {
return false;
}
/* We check the vars */
if(!$this->checkVars($content, $id, $yAlreadySet, $decimalPointRemoved)) {
return false;
}
$this->identifiersId[] = $id;
$this->identifiersContent[] = $content;
$nbCharLastContent = (((strlen($content) + $nbCharId) - $checksumAdded) + $decimalPointRemoved) + $separatorsFound;
if($nbCharToParse - $nbCharLastContent > 0) {
/* If there is more than one content in this array, we parse again */
$otherContent = substr($toParse, $nbCharLastContent, $nbCharToParse);
$nbCharOtherContent = strlen($otherContent);
if($otherContent[0] === chr(29)) {
$otherContent = substr($otherContent, 1);
$nbCharOtherContent--;
}
if($nbCharOtherContent > 0) {
$text = $otherContent;
$this->parseContent($text);
}
}
return true;
}
/**
* Checks if an id exists
*
* @param string $id
* @param bool $yAlreadySet
* @param string $realNameId
*
* @return bool
*/
function idExists($id, &$yAlreadySet, &$realNameId) { // private
$yFound = isset($id[3]) && $id[3] === 'y';
$idVarAdded = substr($id, 0, -1) . 'y';
if(isset($this->identifiersAi[$id])) {
if($yFound) {
$yAlreadySet = false;
}
$realNameId = $id;
return true;
} elseif(!$yFound && isset($this->identifiersAi[$idVarAdded])) {
/* if the id don't exist, we try to find this id with "y" at the last char */
$yAlreadySet = true;
$realNameId = $idVarAdded;
return true;
}
return false;
}
/**
* Finds ID with formated content
*
* @param string $id
* @param bool $yAlreadySet
* @param string $realNameId
* @return mixed
*/
function findIdFormated($id, &$yAlreadySet, &$realNameId) { // private
$pos = strpos($id, ')');
if($pos === false) {
$this->errorTextGS1128 = 'Identifiers must have no more than 4 characters.';
return false;
} else {
if($pos < 3) {
$this->errorTextGS1128 = 'Identifiers must have at least 2 characters.';
return false;
}
$id = substr($id, 1, $pos - 1);
if($this->idExists($id, $yAlreadySet, $realNameId)) {
return $id;
} else {
$this->errorTextGS1128 = 'The identifier ' . $id . ' doesn\'t exist.';
return false;
}
}
}
/**
* Finds ID with non-formated content
*
* @param string $id
* @param bool $yAlreadySet
* @param string $realNameId
* @return mixed
*/
function findIdNotFormated($id, &$yAlreadySet, &$realNameId) { // private
$tofind = $id;
while(strlen($tofind) >= 2) {
if($this->idExists($tofind, $yAlreadySet, $realNameId)) {
return $tofind;
} else {
$tofind = substr($tofind, 0, -1);
}
}
$this->errorTextGS1128 = 'Error in formatting, can\'t find an identifier.';
return false;
}
/**
* Checks confirmity of the content
*
* @param string $content
* @param string $id
* @param string $realNameId
* @return bool
*/
function checkConformity(&$content, $id, $realNameId) { // private
switch($this->identifiersAi[$realNameId][$this->KIND_OF_DATA]) {
case $this->NUMERIC:
$content = str_replace(',', '.', $content);
if(!preg_match("/^[0-9.]+$/", $content)) {
$this->errorTextGS1128 = 'The value of "' . $id . '" must be numerical.';
return false;
}
break;
case $this->DATE_YYMMDD:
$valid_date = true;
if(preg_match("/^[0-9]{6}$/", $content)) {
$year = substr($content, 0, 2);
$month = substr($content, 2, 2);
$day = substr($content, 4, 2);
/* day can be 00 if we only need month and year */
if(intval($month) < 1 || intval($month) > 12 || intval($day) < 0 || intval($day) > 31) {
$valid_date = false;
}
} else {
$valid_date = false;
}
if(!$valid_date) {
$this->errorTextGS1128 = 'The value of "' . $id . '" must be in YYMMDD format.';
return false;
}
break;
}
/* We check the length of the content */
$nbCharContent = strlen($content);
$checksumChar = 0;
$minlengthContent = $this->identifiersAi[$realNameId][$this->MINLENGTH];
$maxlengthContent = $this->identifiersAi[$realNameId][$this->MAXLENGTH];
if($this->identifiersAi[$realNameId][$this->CHECKSUM]) {
$checksumChar++;
}
if($nbCharContent < ($minlengthContent - $checksumChar)) {
if($minlengthContent === $maxlengthContent) {
$this->errorTextGS1128 = 'The value of "' . $id . '" must contain ' . $minlengthContent . ' character(s).';
return false;
} else {
$this->errorTextGS1128 = 'The value of "' . $id . '" must contain between ' . $minlengthContent . ' and ' . $maxlengthContent . ' character(s).';
return false;
}
}
return true;
}
/**
* Verifies the checksum
*
* @param string $content
* @param string $id
* @param int $realNameId
* @param int $checksumAdded
* @return bool
*/
function checkChecksum(&$content, $id, $realNameId, &$checksumAdded) { // private
if($this->identifiersAi[$realNameId][$this->CHECKSUM]) {
$nbCharContent = strlen($content);
$minlengthContent = $this->identifiersAi[$realNameId][$this->MINLENGTH];
if($nbCharContent === ($minlengthContent - 1)) {
/* we need to calculate the checksum */
$content .= $this->calculateChecksumMod10($content);
$checksumAdded++;
} elseif($nbCharContent === $minlengthContent) {
/* we need to check the checksum */
$checksum = $this->calculateChecksumMod10(substr($content, 0, -1));
if(intval($content[$nbCharContent - 1]) !== $checksum) {
$this->errorTextGS1128 = 'The checksum of "(' . $id . ') ' . $content . '" must be: ' . $checksum;
return false;
}
}
}
return true;
}
/**
* Checks vars "y"
*
* @param string $content
* @param string $id
* @param bool $yAlreadySet
* @param int $decimalPointRemoved
* @return bool
*/
function checkVars(&$content, &$id, $yAlreadySet, &$decimalPointRemoved) { // private
$nbCharContent = strlen($content);
/* We check for "y" var in AI */
if($yAlreadySet) {
/* We'll check if we have a decimal point */
if(strpos($content, '.') !== false) {
$this->errorTextGS1128 = 'If you do not use any "y" variable, you have to insert a whole number.';
return false;
}
} elseif($yAlreadySet !== NULL) {
/* We need to replace the "y" var with the position of the decimal point */
$pos = strpos($content, '.');
if($pos === false) {
$this->errorTextGS1128 = 'If you use a "y" variable, you have to insert a decimal number.';
return false;
} else {
$id = str_replace('y', $nbCharContent - ($pos + 1), strtolower($id));
$content = str_replace('.', '', $content);
$decimalPointRemoved++;
}
}
return true;
}
/**
* Checksum Mod10
* @param int $content
* @return int
*/
function calculateChecksumMod10($content) { // private
// Calculating Checksum
// Consider the right-most digit of the message to be in an "odd" position,
// and assign odd/even to each character moving from right to left
// Odd Position = 3, Even Position = 1
// Multiply it by the number
// Add all of that and do 10-(?mod10)
$odd = true;
$checksumValue = 0;
$c = strlen($content);
for($i = $c; $i > 0; $i--) {
if($odd === true) {
$multiplier = 3;
$odd = false;
} else {
$multiplier = 1;
$odd = true;
}
$checksumValue += ($content[$i - 1] * $multiplier);
}
return (10 - $checksumValue % 10) % 10;
}
};
?>

View File

@@ -0,0 +1,164 @@
<?php
/**
* BCGi25.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - Interleaved 2 of 5
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.2 23 jul 2005 Jean-Sébastien Goupil Correct Checksum
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGi25.barcode.php,v 1.8 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.10
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGi25 extends BCGBarcode1D {
var $checksum;
/**
* Constructor
*/
function BCGi25() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
$this->code = array(
'00110', /* 0 */
'10001', /* 1 */
'01001', /* 2 */
'11000', /* 3 */
'00101', /* 4 */
'10100', /* 5 */
'01100', /* 6 */
'00011', /* 7 */
'10010', /* 8 */
'01010' /* 9 */
);
$this->setChecksum(false);
}
function setChecksum($checksum) {
$this->checksum = (bool)$checksum;
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must be even
if($c % 2 !== 0 && $this->checksum === false) {
$this->drawError($im, 'i25 must be even if checksum is false.');
$error_stop = true;
} elseif($c % 2 === 0 && $this->checksum === true) {
$this->drawError($im, 'i25 must be odd if checksum is true.');
$error_stop = true;
}
if($error_stop === false) {
$temp_text = $this->text;
// Checksum
if($this->checksum === true) {
$this->calculateChecksum();
$temp_text .= $this->keys[$this->checksumValue];
}
// Starting Code
$this->drawChar($im, '0000', true);
// Chars
$c = strlen($temp_text);
for($i = 0; $i < $c; $i += 2) {
$temp_bar = '';
$c2 = strlen($this->findCode($temp_text[$i]));
for($j = 0; $j < $c2; $j++) {
$temp_bar .= substr($this->findCode($temp_text[$i]), $j, 1);
$temp_bar .= substr($this->findCode($temp_text[$i + 1]), $j, 1);
}
$this->drawChar($im, $temp_bar, true);
}
// Ending Code
$this->drawChar($im, '100', true);
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$textlength = 7 * strlen($this->text) * $this->scale;
$startlength = 4 * $this->scale;
$checksumlength = 0;
if($this->checksum === true) {
$checksumlength = 7 * $this->scale;
}
$endlength = 4 * $this->scale;
return array($p[0] + $startlength + $textlength + $checksumlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Calculating Checksum
// Consider the right-most digit of the message to be in an "even" position,
// and assign odd/even to each character moving from right to left
// Even Position = 3, Odd Position = 1
// Multiply it by the number
// Add all of that and do 10-(?mod10)
$even = true;
$this->checksumValue = 0;
$c = strlen($this->text);
for($i = $c; $i > 0; $i--) {
if($even === true) {
$multiplier = 3;
$even = false;
} else {
$multiplier = 1;
$even = true;
}
$this->checksumValue += $this->keys[$this->text[$i - 1]] * $multiplier;
}
$this->checksumValue = (10 - $this->checksumValue % 10) % 10;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
};
?>

View File

@@ -0,0 +1,268 @@
<?php
/**
* BCGisbn.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - ISBN-10 and ISBN-13
*
* You can provide an ISBN with 10 digits with or without the checksum.
* You can provide an ISBN with 13 digits with or without the checksum.
* Calculate the ISBN based on the EAN-13 encoding.
*
* The checksum is always displayed.
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.5 13 apr 2007 Jean-Sébastien Goupil
*--------------------------------------------------------------------
* $Id: BCGisbn.barcode.php,v 1.6 2010/02/14 00:25:14 jsgoupil Exp $
* PHP5-Revision: 1.7
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGean13.barcode.php');
class BCGisbn extends BCGean13 {
var $GS1_AUTO = 0; // const
var $GS1_PREFIX978 = 1; // const
var $GS1_PREFIX979 = 2; // const
var $gs1;
var $isbn_created;
var $isbn_text;
var $isbn_textfont;
var $forceOffsetY;
/**
* Constructor
*
* @param int $gs1
* @param string $isbn_text
* @param mixed $textfont2 BCGFont or int
*/
function BCGisbn($gs1 = 0, $isbn_text = '##!!AUTO_LABEL!!##', $isbn_font = null) {
BCGean13::BCGean13();
$this->forceOffsetY = false;
$this->setISBNFont($isbn_font);
$this->setISBNText($isbn_text);
$this->setGS1($gs1);
}
/**
* Saves Text
*
* @param string $text
*/
function parse($text) {
BCGBarcode1D::parse(str_replace(array('-', ' '), '', $text));
$this->createISBNText();
$this->setLabelOffset();
}
/**
* Sets the first numbers of the barcode.
* - GS1_AUTO: Adds 978 before the code
* - GS1_PREFIX978: Adds 978 before the code
* - GS1_PREFIX979: Adds 979 before the code
*
* @param int $gs1
*/
function setGS1($gs1) {
$gs1 = (int)$gs1;
if($gs1 !== $this->GS1_AUTO && $gs1 !== $this->GS1_PREFIX978 && $gs1 !== $this->GS1_PREFIX979) {
$gs1 = $this->GS1_AUTO;
}
$this->gs1 = $gs1;
}
/**
* Sets the font to write the ISBN text on the top of the barcode.
*
* @param mixed $font
*/
function setISBNFont($font) {
if(is_a($font, 'BCGFont')) {
$this->isbn_textfont = $font; // clone
} else if($font === null) {
$this->isbn_textfont = null;
} else {
$this->isbn_textfont = intval($font);
}
$this->setLabelOffset();
}
/**
* Sets the text for the ISBN value.
*
* @param string $isbn_text
*/
function setISBNText($text) {
$this->isbn_text = $text;
$this->createISBNText();
$this->setLabelOffset();
}
function setOffsetY($offsetY) {
BCGean13::setOffsetY($offsetY);
// We force the offsetY, so we won't position based on the label position
$this->forceOffsetY = true;
}
function getMaxSize() {
// We must compute the first digit calculating the width
$null = null;
$this->isLengthCorrect($null);
return BCGean13::getMaxSize();
}
function setLabelOffset() {
BCGean13::setLabelOffset();
if(!empty($this->isbn_created) && !$this->forceOffsetY) {
if(is_a($this->getISBNFont(), 'BCGFont')) {
$f = $this->getISBNFont(); // clone
$f->setText($this->isbn_created);
$val = ($f->getHeight() - $f->getUnderBaseline()) / $this->scale + $this->SIZE_SPACING_FONT;
$this->offsetY = $val;
} elseif($this->getISBNFont() !== 0) {
$val = (imagefontheight($this->getISBNFont()) + 2) / $this->scale;
$this->offsetY = $val;
}
}
}
function isCharsAllowed(&$im) {
$c = strlen($this->text);
// Special case, if we have 10 digits, the last one can be X
if($c === 10) {
if(array_search($this->text[9], $this->keys) === false && $this->text[9] !== 'X') {
$this->drawError($im, 'Char \'' . $this->text[9] . '\' not allowed.');
return false;
}
// Drop the last char
$this->text = substr($this->text, 0, 9);
}
return BCGean13::isCharsAllowed($im);
}
function isLengthCorrect(&$im) {
$c = strlen($this->text);
// If we have 13 chars just flush the last one
if($c === 13) {
$this->text = substr($this->text, 0, 12);
return true;
} elseif($c === 12) {
return true;
} elseif($c === 9 || $c === 10) {
if($c === 10) {
// Before dropping it, we check if it's legal
if(array_search($this->text[9], $this->keys) === false && $this->text[9] !== 'X') {
return false;
}
$this->text = substr($this->text, 0, 9);
}
if($this->gs1 === $this->GS1_AUTO || $this->gs1 === $this->GS1_PREFIX978) {
$this->text = '978' . $this->text;
} elseif($this->gs1 === $this->GS1_PREFIX979) {
$this->text = '979' . $this->text;
}
// We changed the start, recalculate the offset label
BCGean13::setLabelOffset();
return true;
} else {
if($im !== null) {
$this->drawError($im, 'Must provide 9, 10, 12 or 13 digits.');
}
return false;
}
}
/**
* Overloaded method for drawing special label
*
* @param resource $im
*/
function drawText(&$im) {
BCGean13::drawText($im);
if(strlen($this->isbn_created) > 0) {
$pA = $this->getMaxSize();
$pB = BCGBarcode1D::getMaxSize();
$w = $pA[0] - $pB[0];
if(is_a($this->getISBNFont(), 'BCGFont')) {
$textfont = $this->getISBNFont(); // clone
$textfont->setText($this->isbn_created);
$xPosition = ($w / 2) - ($textfont->getWidth() / 2) + $this->offsetX * $this->scale;
$yPosition = $this->offsetY * $this->scale - $this->SIZE_SPACING_FONT;
$textfont->draw($im, $this->colorFg->allocate($im), $xPosition, $yPosition);
} elseif($this->getISBNFont() !== 0) {
$xPosition = ($w / 2) - (strlen($this->isbn_created) / 2) * imagefontwidth($this->getISBNFont()) + $this->offsetX * $this->scale;
$yPosition = $this->offsetY * $this->scale - $this->SIZE_SPACING_FONT - imagefontheight($this->getISBNFont());
imagestring($im, $this->getISBNFont(), $xPosition, $yPosition, $this->isbn_created, $this->colorFg->allocate($im));
}
}
}
function &getISBNFont() {
if($this->isbn_textfont === null) {
return $this->textfont;
} else {
return $this->isbn_textfont;
}
}
function createISBNText() {
if($this->isbn_text === $this->AUTO_LABEL && !empty($this->text)) {
// We try to create the ISBN Text... the hyphen really depends the ISBN agency.
// We just put one before the checksum and one after the GS1 if present.
$c = strlen($this->text);
if($c === 12 || $c === 13) {
// If we have 13 characters now, just transform it temporarily to find the checksum...
// Further in the code we take care of that anyway.
$lastCharacter = '';
if($c === 13) {
$lastCharacter = $this->text[12];
$this->text = substr($this->text, 0, 12);
}
$checksum = $this->processChecksum();
$this->isbn_created = 'ISBN ' . substr($this->text, 0, 3) . '-' . substr($this->text, 3, 9) . '-' . $checksum;
// Put the last character back
if($c === 13) {
$this->text .= $lastCharacter;
}
} elseif($c === 9 || $c === 10) {
$checksum = 0;
for($i = 10; $i >= 2; $i--) {
$checksum += $this->text[10 - $i] * $i;
}
$checksum = 11 - $checksum % 11;
if($checksum === 10) {
$checksum = 'X';
}
$this->isbn_created = 'ISBN ' . substr($this->text, 0, 9) . '-' . $checksum;
} else {
$this->isbn_created = '';
}
} else {
$this->isbn_created = $this->isbn_text;
}
}
};
?>

View File

@@ -0,0 +1,170 @@
<?php
/**
* BCGmsi.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - MSI Plessey
*
*--------------------------------------------------------------------
* Revision History
* v2.0.1 8 mar 2009 Jean-Sébastien Goupil Fix checksum 1 or 2
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.2 23 jul 2005 Jean-Sébastien Goupil Enhance rapidity
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGmsi.barcode.php,v 1.9 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.10
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGmsi extends BCGBarcode1D {
var $checksum;
/**
* Constructor
*/
function BCGmsi() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
$this->code = array(
'01010101', /* 0 */
'01010110', /* 1 */
'01011001', /* 2 */
'01011010', /* 3 */
'01100101', /* 4 */
'01100110', /* 5 */
'01101001', /* 6 */
'01101010', /* 7 */
'10010101', /* 8 */
'10010110' /* 9 */
);
$this->setChecksum(0);
}
function setChecksum($checksum) {
$checksum = intval($checksum);
if($checksum < 0 && $checksum > 2) {
$checksum = 0;
}
$this->checksum = $checksum;
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Checksum
$this->calculateChecksum();
// Starting Code
$this->drawChar($im, '10', true);
// Chars
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->findCode($this->text[$i]), true);
}
$c = count($this->checksumValue);
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->findCode($this->checksumValue[$i]), true);
}
// Ending Code
$this->drawChar($im, '010', true);
$this->drawText($im);
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$textlength = 12 * strlen($this->text) * $this->scale;
$startlength = 3 * $this->scale;
$checksumlength = $this->checksum * 12 * $this->scale;
$endlength = 4 * $this->scale;
return array($p[0] + $startlength + $textlength + $checksumlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Forming a new number
// If the original number is even, we take all even position
// If the original number is odd, we take all odd position
// 123456 = 246
// 12345 = 135
// Multiply by 2
// Add up all the digit in the result (270 : 2+7+0)
// Add up other digit not used.
// 10 - (? Modulo 10). If result = 10, change to 0
$last_text = $this->text;
$this->checksumValue = array();
for($i = 0; $i < $this->checksum; $i++) {
$new_text = '';
$new_number = 0;
$c = strlen($last_text);
if($c % 2 === 0) { // Even
$starting = 1;
} else {
$starting = 0;
}
for($j = $starting; $j < $c; $j += 2) {
$new_text .= $last_text[$j];
}
$new_text = strval(intval($new_text) * 2);
$c2 = strlen($new_text);
for($j = 0; $j < $c2; $j++) {
$new_number += intval($new_text[$j]);
}
for($j = ($starting === 0) ? 1 : 0; $j < $c; $j += 2) {
$new_number += intval($last_text[$j]);
}
$new_number = (10 - $new_number % 10) % 10;
$this->checksumValue[] = $new_number;
$last_text .= $new_number;
}
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
$ret = '';
$c = count($this->checksumValue);
for($i = 0; $i < $c; $i++) {
$ret .= $this->keys[$this->checksumValue[$i]];
}
return $ret;
}
return false;
}
};
?>

View File

@@ -0,0 +1,107 @@
<?php
/**
* BCGothercode.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - othercode
*
* Other Codes
* Starting with a bar and altern to space, bar, ...
* 0 is the smallest
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 2 jan 2006 Jean-Sébastien Goupil Correct error if $textfont was empty
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGothercode.barcode.php,v 1.9 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.10
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
// Function str_split is not available for PHP4. So we emulate it here.
if (!function_exists('str_split')) {
function str_split($string, $split_length = 1) {
$array = explode("\r\n", chunk_split($string, $split_length));
array_pop($array);
return $array;
}
}
class BCGothercode extends BCGBarcode1D {
/**
* Constructor
*/
function BCGothercode() {
BCGBarcode1D::BCGBarcode1D();
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$this->drawChar($im, $this->text, true);
$this->drawText($im);
}
function getLabel() {
$label = $this->label;
if($this->label === $this->AUTO_LABEL) {
$label = '';
}
return $label;
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$array = str_split($this->text, 1);
$textlength = (array_sum($array) + count($array)) * $this->scale;
return array($p[0] + $textlength, $p[1]);
}
/**
* Overloaded method for drawing special label
*
* @param resource $im
*/
function drawText(&$im) {
if($this->label !== $this->AUTO_LABEL && $this->label !== '') {
$pA = $this->getMaxSize();
$pB = BCGBarcode1D::getMaxSize();
$w = $pA[0] - $pB[0];
if(is_a($this->textfont, 'BCGFont')) {
$textfont = $this->textfont; // clone
$textfont->setText($this->label);
$xPosition = ($w / 2) - $textfont->getWidth() / 2 + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $textfont->getHeight() - $textfont->getUnderBaseline() + $this->SIZE_SPACING_FONT + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
$textfont->draw($im, $text_color, $xPosition, $yPosition);
} elseif($this->textfont !== 0) {
$xPosition = ($w / 2) - (strlen($this->label) * imagefontwidth($this->textfont)) / 2 + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $this->offsetY * $this->scale + $this->SIZE_SPACING_FONT;
$text_color = $this->colorFg->allocate($im);
imagestring($im, $this->textfont, $xPosition, $yPosition, $this->label, $text_color);
}
}
}
};
?>

View File

@@ -0,0 +1,135 @@
<?php
/**
* BCGpostnet.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - PostNet
*
* ################ NOT TESTED ################
*
*--------------------------------------------------------------------
* Revision History
* v2.0.1 8 mar 2009 Jean-Sébastien Goupil Fix padding for the barcode
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil PHP5.1 compatible
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added + Redesign output
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGpostnet.barcode.php,v 1.12 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.13
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGpostnet extends BCGBarcode1D {
/**
* Constructor
*/
function BCGpostnet() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
$this->code = array(
'11000', /* 0 */
'00011', /* 1 */
'00101', /* 2 */
'00110', /* 3 */
'01001', /* 4 */
'01010', /* 5 */
'01100', /* 6 */
'10001', /* 7 */
'10010', /* 8 */
'10100' /* 9 */
);
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must contain 5, 9 or 11 chars
if($c !== 5 && $c !== 9 && $c !== 11) {
$this->drawError($im, 'Must contain 5, 9 or 11 chars.');
$error_stop = true;
}
if($error_stop === false) {
// Checksum
$checksum = 0;
for($i = 0; $i < $c; $i++) {
$checksum += intval($this->text[$i]);
}
$checksum = 10 - ($checksum % 10);
// Starting Code
$this->drawChar($im, '1');
// Code
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->findCode($this->text[$i]));
}
// Checksum
$this->drawChar($im, $this->findCode($checksum));
//Ending Code
$this->drawChar($im, '1');
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$c = strlen($this->text);
$startlength = 6 * $this->scale;
$textlength = $c * 5 * 6 * $this->scale;
$checksumlength = 5 * 6 * $this->scale;
$endlength = 6 * $this->scale;
// We remove the white on the right
$removelength = - 3 * $this->scale;
return array($p[0] + $startlength + $textlength + $checksumlength + $endlength + $removelength, $p[1]);
}
/**
* Overloaded method for drawing special barcode
*
* @param resource $im
* @param string $code
* @param boolean $last
*/
function drawChar(&$im, $code, $last = false) {
$c = strlen($code);
for($i = 0; $i < $c; $i++) {
if($code[$i] === '0') {
$posY = $this->thickness / 2;
} else {
$posY = 0;
}
$this->drawFilledRectangle($im, $this->positionX, $posY, $this->positionX + 2, $this->thickness, $this->COLOR_FG);
$this->positionX += 2 * 3;
}
}
};
?>

View File

@@ -0,0 +1,161 @@
<?php
/**
* BCGs25.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - Standard 2 of 5
*
* NOTE: It is really tough to read this barcode !
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.2 23 jul 2005 Jean-Sébastien Goupil Correct Checksum
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGs25.barcode.php,v 1.8 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.10
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGs25 extends BCGBarcode1D {
var $checksum;
/**
* Constructor
*/
function BCGs25() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
$this->code = array(
'0000202000', /* 0 */
'2000000020', /* 1 */
'0020000020', /* 2 */
'2020000000', /* 3 */
'0000200020', /* 4 */
'2000200000', /* 5 */
'0020200000', /* 6 */
'0000002020', /* 7 */
'2000002000', /* 8 */
'0020002000' /* 9 */
);
$this->setChecksum(false);
}
function setChecksum($checksum) {
$this->checksum = (bool)$checksum;
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must be even
if($c % 2 !== 0 && $this->checksum === false) {
$this->drawError($im, 's25 must be even if checksum is false.');
$error_stop = true;
} elseif($c % 2 === 0 && $this->checksum === true) {
$this->drawError($im, 's25 must be odd if checksum is true.');
$error_stop = true;
}
if($error_stop === false) {
$temp_text = $this->text;
// Checksum
if($this->checksum === true) {
$this->calculateChecksum();
$temp_text .= $this->keys[$this->checksumValue];
}
// Starting Code
$this->drawChar($im, '101000', true);
// Chars
$c = strlen($temp_text);
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, $this->findCode($temp_text[$i]), true);
}
// Ending Code
$this->drawChar($im, '10001', true);
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$c = strlen($this->text);
$startlength = 8 * $this->scale;
$textlength = $c * 14 * $this->scale;
$checksumlength = 0;
if($c % 2 !== 0) {
$checksumlength = 14 * $this->scale;
}
$endlength = 7 * $this->scale;
return array($p[0] + $startlength + $textlength + $checksumlength + $endlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Calculating Checksum
// Consider the right-most digit of the message to be in an "even" position,
// and assign odd/even to each character moving from right to left
// Even Position = 3, Odd Position = 1
// Multiply it by the number
// Add all of that and do 10-(?mod10)
$even = true;
$this->checksumValue = 0;
$c = strlen($this->text);
for($i = $c; $i > 0; $i--) {
if($even === true) {
$multiplier = 3;
$even = false;
} else {
$multiplier = 1;
$even = true;
}
$this->checksumValue += $this->keys[$this->text[$i - 1]] * $multiplier;
}
$this->checksumValue = (10 - $this->checksumValue % 10) % 10;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
};
?>

View File

@@ -0,0 +1,362 @@
<?php
/**
* BCGupca.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - UPC-A
*
* UPC-A contains
* - 2 system digits (1 not provided, a 0 is added automatically)
* - 5 manufacturer code digits
* - 5 product digits
* - 1 checksum digit
*
* The checksum is always displayed.
*
*--------------------------------------------------------------------
* Revision History
* v2.0.1 8 mar 2009 Jean-Sébastien Goupil Fix padding for the barcode
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3 6 feb 2006 Jean-Sébastien Goupil Fix label position + Using correctly static method
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.2 23 jul 2005 Jean-Sébastien Goupil Enhance rapidity
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added + correcting output when text was present
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGupca.barcode.php,v 1.12 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.15
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGupca extends BCGBarcode1D {
var $codeParity = array();
/**
* Constructor
*/
function BCGupca() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
// Left-Hand Odd Parity starting with a space
// Left-Hand Even Parity is the inverse (0=0012) starting with a space
// Right-Hand is the same of Left-Hand starting with a bar
$this->code = array(
'2100', /* 0 */
'1110', /* 1 */
'1011', /* 2 */
'0300', /* 3 */
'0021', /* 4 */
'0120', /* 5 */
'0003', /* 6 */
'0201', /* 7 */
'0102', /* 8 */
'2001' /* 9 */
);
// Parity, 0=Odd, 1=Even for manufacturer code. Depending on 1st System Digit
$this->codeParity = array(
array(0,0,0,0,0), /* 0 */
array(0,1,0,1,1), /* 1 */
array(0,1,1,0,1), /* 2 */
array(0,1,1,1,0), /* 3 */
array(1,0,0,1,1), /* 4 */
array(1,1,0,0,1), /* 5 */
array(1,1,1,0,0), /* 6 */
array(1,0,1,0,1), /* 7 */
array(1,0,1,1,0), /* 8 */
array(1,1,0,1,0) /* 9 */
);
}
function parse($text) {
BCGBarcode1D::parse($text);
$this->setLabelOffset();
}
function setFont($font) {
BCGBarcode1D::setFont($font);
$this->setLabelOffset();
}
function setLabel($label) {
BCGBarcode1D::setLabel($label);
$this->setLabelOffset();
}
function setOffsetX($offsetX) {
BCGBarcode1D::setOffsetX($offsetX);
$this->setLabelOffset();
}
function setScale($scale) {
BCGBarcode1D::setScale($scale);
$this->setLabelOffset();
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must contain 11 chars
if($c !== 11) {
$this->drawError($im, 'Must contain 11 chars, the 12th digit is automatically added.');
$error_stop = true;
}
if($error_stop === false) {
// The following code is exactly the same as EAN13. We just add a 0 in front of the code !
$this->text = '0'.$this->text; // We will remove it at the end... don't worry
// Checksum
$this->calculateChecksum();
$temp_text = $this->text . $this->keys[$this->checksumValue];
// Starting Code
$this->drawChar($im, '000', true);
// Draw Second Code
$this->drawChar($im, $this->findCode($temp_text[1]), false);
// Draw Manufacturer Code
for($i = 0; $i < 5; $i++) {
$this->drawChar($im, BCGupca::inverse($this->findCode($temp_text[$i + 2]), $this->codeParity[$temp_text[0]][$i]), false);
}
// Draw Center Guard Bar
$this->drawChar($im, '00000', false);
// Draw Product Code
for($i = 7; $i < 13; $i++) {
$this->drawChar($im, $this->findCode($temp_text[$i]), true);
}
// Draw Right Guard Bar
$this->drawChar($im, '000', true);
$this->drawText($im);
// We remove the 0 in front, as we said :)
$this->text = substr($this->text, 1);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$startlength = 3 * $this->scale;
$centerlength = 5 * $this->scale;
$textlength = 12 * 7 * $this->scale;
$endlength = 3 * $this->scale;
$lastcharlength = $this->getEndPosition() + 2;
return array($p[0] + $startlength + $centerlength + $textlength + $endlength + $lastcharlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Calculating Checksum
// Consider the right-most digit of the message to be in an "odd" position,
// and assign odd/even to each character moving from right to left
// Odd Position = 3, Even Position = 1
// Multiply it by the number
// Add all of that and do 10-(?mod10)
$odd = true;
$this->checksumValue = 0;
$c = strlen($this->text);
for($i = $c; $i > 0; $i--) {
if($odd === true) {
$multiplier = 3;
$odd = false;
} else {
$multiplier = 1;
$odd = true;
}
if(!isset($this->keys[$this->text[$i - 1]])) {
return;
}
$this->checksumValue += $this->keys[$this->text[$i - 1]] * $multiplier;
}
$this->checksumValue = (10 - $this->checksumValue % 10) % 10;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
/**
* Overloaded method for drawing special label
*
* @param resource $im
*/
function drawText(&$im) {
if($this->label !== $this->AUTO_LABEL) {
BCGBarcode1D::drawText($im);
} elseif($this->label !== '') {
$temp_text = $this->text . $this->keys[$this->checksumValue];
if(is_a($this->textfont, 'BCGFont')) {
$code1 = 0;
$code2 = 0;
$this->textfont->setText($temp_text);
$this->drawExtendedBars($im, $this->textfont->getHeight(), $code1, $code2);
// We need to separate the text, one on the left and one on the right, one starting and one ending
$text0 = substr($temp_text, 1, 1);
$text1 = substr($temp_text, 2, 5);
$text2 = substr($temp_text, 7, 5);
$text3 = substr($temp_text, 12, 1);
$font0 = $this->textfont; // clone
$font1 = $this->textfont; // clone
$font2 = $this->textfont; // clone
$font3 = $this->textfont; // clone
$font0->setText($text0);
$font1->setText($text1);
$font2->setText($text2);
$font3->setText($text3);
$xPosition0 = $this->offsetX * $this->scale - $font0->getWidth() - 4; // -4 is just for beauty;
$xPosition3 = $this->offsetX * $this->scale + $this->positionX * $this->scale + 2;
$yPosition0 = $this->thickness * $this->scale + $font0->getHeight() / 2 + $this->offsetY * $this->scale;
$xPosition1 = ($this->scale * 36 - $font1->getWidth()) / 2 + $code1 * $this->scale + $this->offsetX * $this->scale;
$xPosition2 = ($this->scale * 37 - $font2->getWidth()) / 2 + $code2 * $this->scale + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $this->textfont->getHeight() + $this->SIZE_SPACING_FONT + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
$font0->draw($im, $text_color, $xPosition0, $yPosition0);
$font1->draw($im, $text_color, $xPosition1, $yPosition);
$font2->draw($im, $text_color, $xPosition2, $yPosition);
$font3->draw($im, $text_color, $xPosition3, $yPosition0);
} elseif($this->textfont !== 0) {
$code1 = 0;
$code2 = 0;
$this->drawExtendedBars($im, 9, $code1, $code2);
$xPosition0 = $this->offsetX * $this->scale - imagefontwidth($this->textfont);
$xPosition3 = $this->offsetX * $this->scale + $this->positionX * $this->scale + 2;
$yPosition0 = $this->thickness * $this->scale - imagefontheight($this->textfont) / 2 + $this->offsetY * $this->scale;
$xPosition1 = ($this->scale * 36 - imagefontwidth($this->textfont) * 5) / 2 + $code1 * $this->scale + $this->offsetX * $this->scale;
$xPosition2 = ($this->scale * 37 - imagefontwidth($this->textfont) * 5) / 2 + $code2 * $this->scale + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
imagechar($im, $this->textfont, $xPosition0, $yPosition0, $temp_text[1], $text_color);
imagestring($im, $this->textfont, $xPosition1, $yPosition, substr($temp_text, 2, 5), $text_color);
imagestring($im, $this->textfont, $xPosition2, $yPosition, substr($temp_text, 7, 5), $text_color);
imagechar($im, $this->textfont, $xPosition3, $yPosition0, $temp_text[12], $text_color);
}
}
}
function setLabelOffset() {
$label = $this->getLabel();
if(!empty($label)) {
if(is_a($this->textfont, 'BCGFont')) {
$f = $this->textfont; // clone
$f->setText(substr($label, 0, 1));
$val = ($f->getWidth() + 5) / $this->scale;
if($val > $this->offsetX) {
$this->offsetX = $val;
}
} elseif($this->textfont !== 0) {
$val = (imagefontwidth($this->textfont) + 2) / $this->scale;
if($val > $this->offsetX) {
$this->offsetX = $val;
}
}
}
}
function drawExtendedBars(&$im, $plus, &$code1, &$code2) {
$temp_text = $this->text . $this->keys[$this->checksumValue];
$rememberX = $this->positionX;
$rememberH = $this->thickness;
// We increase the bars
// First 2 Bars
$this->thickness = $this->thickness + ceil($plus / $this->scale);
$this->positionX = 0;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
// Attemping to increase the 2 following bars
$this->positionX += 1;
$code1 = $this->positionX;
$temp_value = $this->findCode($temp_text[1]);
$this->drawChar($im, $temp_value, false);
$code1 = $this->positionX;
// Center Guard Bar
$this->positionX += 36;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
$code2 = $this->positionX;
// Attemping to increase the 2 last bars
$this->positionX += 37;
$temp_value = $this->findCode($temp_text[12]);
$this->drawChar($im, $temp_value, true);
// Completly last bars
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX = $rememberX;
$this->thickness = $rememberH;
}
function getEndPosition() {
if($this->label === $this->AUTO_LABEL) {
$this->calculateChecksum();
if(is_a($this->textfont, 'BCGFont')) {
$f = $this->textfont; // clone
$f->setText($this->checksumValue);
return $f->getWidth();
} elseif($this->textfont !== 0) {
return imagefontwidth($this->textfont);
}
}
return 0;
}
function inverse($text, $inverse = 1) { // static
if($inverse === 1) {
$text = strrev($text);
}
return $text;
}
};
?>

View File

@@ -0,0 +1,395 @@
<?php
/**
* BCGupce.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - UPC-E
*
* You can provide a UPC-A code (without dash), the code will transform
* it into a UPC-E format if it's possible.
* UPC-E contains
* - 1 system digits (not displayed but coded with parity)
* - 6 digits
* - 1 checksum digit (not displayed but coded with parity)
*
* The text returned is the UPC-E without the checksum.
* The checksum is always displayed.
*
*--------------------------------------------------------------------
* Revision History
* v2.0.1 8 mar 2009 Jean-Sébastien Goupil Fix padding for the barcode
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3 6 feb 2006 Jean-Sébastien Goupil Fix label position + Using correctly static method
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.2 23 jul 2005 Jean-Sébastien Goupil Enhance rapidity
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGupce.barcode.php,v 1.12 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.16
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGupce extends BCGBarcode1D {
var $codeParity = array();
/**
* Constructor
*/
function BCGupce() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
// Odd Parity starting with a space
// Even Parity is the inverse (0=0012) starting with a space
$this->code = array(
'2100', /* 0 */
'1110', /* 1 */
'1011', /* 2 */
'0300', /* 3 */
'0021', /* 4 */
'0120', /* 5 */
'0003', /* 6 */
'0201', /* 7 */
'0102', /* 8 */
'2001' /* 9 */
);
// Parity, 0=Odd, 1=Even for manufacturer code. Depending on 1st System Digit and Checksum
$this->codeParity = array(
array(
array(1,1,1,0,0,0), /* 0,0 */
array(1,1,0,1,0,0), /* 0,1 */
array(1,1,0,0,1,0), /* 0,2 */
array(1,1,0,0,0,1), /* 0,3 */
array(1,0,1,1,0,0), /* 0,4 */
array(1,0,0,1,1,0), /* 0,5 */
array(1,0,0,0,1,1), /* 0,6 */
array(1,0,1,0,1,0), /* 0,7 */
array(1,0,1,0,0,1), /* 0,8 */
array(1,0,0,1,0,1) /* 0,9 */
),
array(
array(0,0,0,1,1,1), /* 0,0 */
array(0,0,1,0,1,1), /* 0,1 */
array(0,0,1,1,0,1), /* 0,2 */
array(0,0,1,1,1,0), /* 0,3 */
array(0,1,0,0,1,1), /* 0,4 */
array(0,1,1,0,0,1), /* 0,5 */
array(0,1,1,1,0,0), /* 0,6 */
array(0,1,0,1,0,1), /* 0,7 */
array(0,1,0,1,1,0), /* 0,8 */
array(0,1,1,0,1,0) /* 0,9 */
)
);
}
function parse($text) {
BCGBarcode1D::parse($text);
$this->setLabelOffset();
}
function setFont($font) {
BCGBarcode1D::setFont($font);
$this->setLabelOffset();
}
function setLabel($label) {
BCGBarcode1D::setLabel($label);
$this->setLabelOffset();
}
function setOffsetX($offsetX) {
BCGBarcode1D::setOffsetX($offsetX);
$this->setLabelOffset();
}
function setScale($scale) {
BCGBarcode1D::setScale($scale);
$this->setLabelOffset();
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must contain 11 chars
// Must contain 8 chars (if starting with upce directly)
// First Chars must be 0 or 1
if($c !== 11 && $c !== 6) {
$this->drawError($im, 'Provide an UPC-A (11 chars) or');
$this->drawError($im, 'You can also provide UPC-E directly (6 chars).');
$error_stop = true;
} elseif($this->text[0] !== '0' && $this->text[0] !== '1' && $c !== 6) {
$this->drawError($im, 'Must start with 0 or 1.');
$error_stop = true;
}
if($error_stop === false) {
if($c !== 6) {
// Checking if UPC-A is convertible
$upce = '';
if(substr($this->text, 3, 3) === '000' || substr($this->text, 3, 3) === '100' || substr($this->text, 3, 3) === '200') { // manufacturer code ends with 100,200 or 300
if(substr($this->text, 6, 2) === '00') { // Product must start with 00
$upce = substr($this->text, 1, 2) . substr($this->text, 8, 3) . substr($this->text, 3, 1);
} else {
$error_stop = true;
}
} elseif(substr($this->text, 4, 2) === '00') { // manufacturer code ends with 00
if(substr($this->text, 6, 3) === '000') { // Product must start with 000
$upce = substr($this->text, 1, 3) . substr($this->text, 9, 2) . '3';
} else {
$error_stop = true;
}
} elseif(substr($this->text, 5, 1) === '0') { // manufacturer code ends with 0
if(substr($this->text, 6, 4) === '0000') { // Product must start with 0000
$upce = substr($this->text, 1, 4) . substr($this->text, 10, 1) . '4';
} else {
$error_stop = true;
}
} else { // No zero leading at manufacturer code
if(substr($this->text, 6, 4) === '0000' && intval(substr($this->text, 10, 1)) >= 5 && intval(substr($this->text, 10, 1)) <= 9) { // Product must start with 0000 and must end by 5,6,7,8 or 9
$upce = substr($this->text, 1, 5) . substr($this->text, 10, 1);
} else {
$error_stop = true;
}
}
} else {
$upce = $this->text;
}
if($error_stop === false) {
if($c === 6) {
// We convert UPC-E to UPC-A to find the checksum
if($this->text[5] === '0' || $this->text[5] === '1' || $this->text[5] === '2') {
$upca = substr($this->text, 0, 2) . $this->text[5] . '0000' . substr($this->text, 2, 3);
} elseif($this->text[5] === '3') {
$upca = substr($this->text, 0, 3) . '00000' . substr($this->text, 3, 2);
} elseif($this->text[5] === '4') {
$upca = substr($this->text, 0, 4) . '00000' . $this->text[4];
} else {
$upca = substr($this->text, 0, 5) . '0000' . $this->text[5];
}
$this->text = '0' . $upca;
}
$this->calculateChecksum();
// Starting Code
$this->drawChar($im, '000', true);
$c = strlen($upce);
for($i = 0; $i < $c; $i++) {
$this->drawChar($im, BCGupce::inverse($this->findCode($upce[$i]), $this->codeParity[$this->text[0]][$this->checksumValue][$i]), false);
}
// Draw Center Guard Bar
$this->drawChar($im, '00000', false);
// Draw Right Bar
$this->drawChar($im, '0', true);
$this->text = $this->text[0] . $upce;
$this->drawText($im);
} else {
$this->drawError($im, 'Your UPC-A can\'t be converted to UPC-E.');
}
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$startlength = 3 * $this->scale;
$centerlength = 5 * $this->scale;
$textlength = 6 * 7 * $this->scale;
$endlength = $this->scale;
$lastcharlength = $this->getEndPosition() + 2;
return array($p[0] + $startlength + $centerlength + $textlength + $endlength + $lastcharlength, $p[1]);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Calculating Checksum
// Consider the right-most digit of the message to be in an "odd" position,
// and assign odd/even to each character moving from right to left
// Odd Position = 3, Even Position = 1
// Multiply it by the number
// Add all of that and do 10-(?mod10)
$odd = true;
$this->checksumValue = 0;
$c = strlen($this->text);
for($i = $c; $i > 0; $i--) {
if($odd === true) {
$multiplier = 3;
$odd = false;
} else {
$multiplier = 1;
$odd = true;
}
if(!isset($this->keys[$this->text[$i - 1]])) {
return;
}
$this->checksumValue += $this->keys[$this->text[$i - 1]] * $multiplier;
}
$this->checksumValue = (10 - $this->checksumValue % 10) % 10;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
/**
* Overloaded method for drawing special label
*
* @param resource $im
*/
function drawText(&$im) {
if($this->label !== $this->AUTO_LABEL) {
BCGBarcode1D::drawText($im);
} elseif($this->label !== '') {
$temp_text = $this->text . $this->keys[$this->checksumValue];
if(is_a($this->textfont, 'BCGFont')) {
$thic->code1 = 0;
$this->textfont->setText($temp_text);
$this->drawExtendedBars($im, $this->textfont->getHeight(), $code1);
// We need to separate the text, one on the left and one on the right, one starting and one ending
$text0 = substr($temp_text, 0, 1);
$text1 = substr($temp_text, 1, 6);
$text2 = substr($temp_text, 7, 1);
$font0 = $this->textfont; // clone
$font1 = $this->textfont; // clone
$font2 = $this->textfont; // clone
$font0->setText($text0);
$font1->setText($text1);
$font2->setText($text2);
$xPosition0 = $this->offsetX * $this->scale - $font0->getWidth() - 4; // -4 is just for beauty;
$xPosition2 = $this->offsetX * $this->scale + $this->positionX * $this->scale + 2;
$yPosition0 = $this->thickness * $this->scale + $font0->getHeight() / 2 + $this->offsetY * $this->scale;
$xPosition1 = ($this->scale * 46 - $font1->getWidth()) / 2 + $code1 * $this->scale + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $this->textfont->getHeight() + $this->SIZE_SPACING_FONT + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
$font0->draw($im, $text_color, $xPosition0, $yPosition0);
$font1->draw($im, $text_color, $xPosition1, $yPosition);
$font2->draw($im, $text_color, $xPosition2, $yPosition0);
} elseif($this->textfont !== 0) {
$thic->code1 = 0;
$this->drawExtendedBars($im, 9, $code1);
$xPosition0 = $this->offsetX * $this->scale - imagefontwidth($this->textfont);
$xPosition2 = $this->offsetX * $this->scale + $this->positionX * $this->scale + 2;
$yPosition0 = $this->thickness * $this->scale - imagefontheight($this->textfont) / 2 + $this->offsetY * $this->scale;
$xPosition1 = ($this->scale * 46 - imagefontwidth($this->textfont) * 6) / 2 + $code1 * $this->scale + $this->offsetX * $this->scale;
$yPosition = $this->thickness * $this->scale + $this->offsetY * $this->scale;
$text_color = $this->colorFg->allocate($im);
imagechar($im, $this->textfont, $xPosition0, $yPosition0, $temp_text[0], $text_color);
imagestring($im, $this->textfont, $xPosition1, $yPosition, substr($temp_text, 1, 6), $text_color);
imagechar($im, $this->textfont, $xPosition2, $yPosition0, $temp_text[7], $text_color);
}
}
}
function drawExtendedBars(&$im, $plus, &$code1) {
$rememberX = $this->positionX;
$rememberH = $this->thickness;
// We increase the bars
$this->thickness = $this->thickness + ceil($plus / $this->scale);
$this->positionX = 0;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
$code1 = $this->positionX;
// Last Bars
$this->positionX += 46;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX += 2;
$this->drawSingleBar($im, $this->COLOR_FG);
$this->positionX = $rememberX;
$this->thickness = $rememberH;
}
function getEndPosition() {
if($this->label === $this->AUTO_LABEL) {
$this->calculateChecksum();
if(is_a($this->textfont, 'BCGFont')) {
$f = $this->textfont; // clone
$f->setText($this->checksumValue);
return $f->getWidth();
} elseif($this->textfont !== 0) {
return imagefontwidth($this->textfont);
}
}
return 0;
}
function setLabelOffset() {
$label = $this->getLabel();
if(!empty($label)) {
if(is_a($this->textfont, 'BCGFont')) {
$f = $this->textfont; // clone
$f->setText(substr($label, 0, 1));
$val = ($f->getWidth() + 5) / $this->scale;
if($val > $this->offsetX) {
$this->offsetX = $val;
}
} elseif($this->textfont !== 0) {
$val = (imagefontwidth($this->textfont) + 2) / $this->scale;
if($val > $this->offsetX) {
$this->offsetX = $val;
}
}
}
}
function inverse($text, $inverse = 1) { // static
if($inverse === 1) {
$text = strrev($text);
}
return $text;
}
};
?>

View File

@@ -0,0 +1,207 @@
<?php
/**
* BCGupcext2.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - UPC Supplemental Barcode 2 digits
*
* Working with UPC-A, UPC-E, EAN-13, EAN-8
* This includes 2 digits (normaly for publications)
* Must be placed next to UPC or EAN Code
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3 6 feb 2006 Jean-Sébastien Goupil Using correctly static method
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil PHP5.1 compatible
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added + correcting output error
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGupcext2.barcode.php,v 1.10 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.13
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGupcext2 extends BCGBarcode1D {
var $codeParity = array();
/**
* Constructor
*/
function BCGupcext2() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
$this->code = array(
'2100', /* 0 */
'1110', /* 1 */
'1011', /* 2 */
'0300', /* 3 */
'0021', /* 4 */
'0120', /* 5 */
'0003', /* 6 */
'0201', /* 7 */
'0102', /* 8 */
'2001' /* 9 */
);
// Parity, 0=Odd, 1=Even. Depending on ?%4
$this->codeParity = array(
array(0,0), /* 0 */
array(0,1), /* 1 */
array(1,0), /* 2 */
array(1,1) /* 3 */
);
}
function parse($text) {
BCGBarcode1D::parse($text);
$this->setLabelOffset();
}
function setFont($font) {
BCGBarcode1D::setFont($font);
$this->setLabelOffset();
}
function setLabel($label) {
BCGBarcode1D::setLabel($label);
$this->setLabelOffset();
}
function setOffsetY($offsetY) {
BCGBarcode1D::setOffsetY($offsetY);
$this->setLabelOffset();
}
function setScale($scale) {
BCGBarcode1D::setScale($scale);
$this->setLabelOffset();
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must contain 2 chars
if($c !== 2) {
$this->drawError($im, 'Must contain 2 chars.');
$error_stop = true;
}
if($error_stop === false) {
// Starting Code
$this->drawChar($im, '001', true);
// Code
for($i = 0; $i < 2; $i++) {
$this->drawChar($im, BCGupcext2::inverse($this->findCode($this->text[$i]), $this->codeParity[intval($this->text) % 4][$i]), false);
if($i === 0) {
$this->DrawChar($im, '00', false); // Inter-char
}
}
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$startlength = 4 * $this->scale;
$textlength = 2 * 7 * $this->scale;
$intercharlength = 2 * $this->scale;
$label = $this->getLabel();
$textHeight = 0;
if(!empty($label)) {
if(is_a($this->textfont, 'BCGFont')) {
$textfont = $this->textfont; // clone
$textfont->setText($label);
$textHeight = $textfont->getHeight() + $this->SIZE_SPACING_FONT;
} elseif($this->textfont !== 0) {
$textHeight = imagefontheight($this->textfont) + $this->SIZE_SPACING_FONT;
}
}
return array($p[0] + $startlength + $textlength + $intercharlength, $p[1] - $textHeight);
}
/**
* Overloaded method for drawing special label
*
* @param resource $im
*/
function drawText(&$im) {
$label = $this->getLabel();
if(!empty($label)) {
$pA = $this->getMaxSize();
$pB = BCGBarcode1D::getMaxSize();
$w = $pA[0] - $pB[0];
if(is_a($this->textfont, 'BCGFont')) {
$textfont = $this->textfont; // clone
$textfont->setText($label);
$xPosition = ($w / 2) - ($textfont->getWidth() / 2) + $this->offsetX * $this->scale;
$yPosition = $this->offsetY * $this->scale - $this->SIZE_SPACING_FONT;
$textfont->draw($im, $this->colorFg->allocate($im), $xPosition, $yPosition);
} elseif($this->textfont !== 0) {
$xPosition = ($w / 2) - (strlen($label) / 2) * imagefontwidth($this->textfont) + $this->offsetX * $this->scale;
$yPosition = $this->offsetY * $this->scale - $this->SIZE_SPACING_FONT - imagefontheight($this->textfont);
imagestring($im, $this->textfont, $xPosition, $yPosition, $label, $this->colorFg->allocate($im));
}
}
}
function setLabelOffset() {
$label = $this->getLabel();
if(!empty($label)) {
if(is_a($this->textfont, 'BCGFont')) {
$f = $this->textfont; // clone
$f->setText($label);
$val = ($f->getHeight() - $f->getUnderBaseline()) / $this->scale + $this->SIZE_SPACING_FONT;
if($val > $this->offsetY) {
$this->offsetY = $val;
}
} elseif($this->textfont !== 0) {
$val = (imagefontheight($this->textfont) + 2) / $this->scale;
if($val > $this->offsetY) {
$this->offsetY = $val;
}
}
}
}
function inverse($text, $inverse = 1) { // static
if($inverse === 1) {
$text = strrev($text);
}
return $text;
}
};
?>

View File

@@ -0,0 +1,263 @@
<?php
/**
* BCGupcext5.barcode.php
*--------------------------------------------------------------------
*
* Sub-Class - UPC Supplemental Barcode 2 digits
*
* Working with UPC-A, UPC-E, EAN-13, EAN-8
* This includes 5 digits (normaly for suggested retail price)
* Must be placed next to UPC or EAN Code
* If 90000 -> No suggested Retail Price
* If 99991 -> Book Complimentary (normally free)
* If 90001 to 98999 -> Internal Purpose of Publisher
* If 99990 -> Used by the National Association of College Stores to mark used books
* If 0xxxx -> Price Expressed in British Pounds (xx.xx)
* If 5xxxx -> Price Expressed in U.S. dollars (US$xx.xx)
*
*--------------------------------------------------------------------
* Revision History
* v2.0.0 23 apr 2008 Jean-Sébastien Goupil New Version Update
* v1.2.3 6 feb 2006 Jean-Sébastien Goupil Using correctly static method
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil Checksum separated + PHP5.1 compatible
* v1.2.1 27 jun 2005 Jean-Sébastien Goupil Font support added
* V1.00 17 jun 2004 Jean-Sebastien Goupil
*--------------------------------------------------------------------
* $Id: BCGupcext5.barcode.php,v 1.10 2009/11/09 04:13:35 jsgoupil Exp $
* PHP5-Revision: 1.13
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGBarcode1D.php');
class BCGupcext5 extends BCGBarcode1D {
var $codeParity = array();
/**
* Constructor
*/
function BCGupcext5() {
BCGBarcode1D::BCGBarcode1D();
$this->keys = array('0','1','2','3','4','5','6','7','8','9');
$this->code = array(
'2100', /* 0 */
'1110', /* 1 */
'1011', /* 2 */
'0300', /* 3 */
'0021', /* 4 */
'0120', /* 5 */
'0003', /* 6 */
'0201', /* 7 */
'0102', /* 8 */
'2001' /* 9 */
);
// Parity, 0=Odd, 1=Even. Depending Checksum
$this->codeParity = array(
array(1,1,0,0,0), /* 0 */
array(1,0,1,0,0), /* 1 */
array(1,0,0,1,0), /* 2 */
array(1,0,0,0,1), /* 3 */
array(0,1,1,0,0), /* 4 */
array(0,0,1,1,0), /* 5 */
array(0,0,0,1,1), /* 6 */
array(0,1,0,1,0), /* 7 */
array(0,1,0,0,1), /* 8 */
array(0,0,1,0,1) /* 9 */
);
}
function parse($text) {
BCGBarcode1D::parse($text);
$this->setLabelOffset();
}
function setFont($font) {
BCGBarcode1D::setFont($font);
$this->setLabelOffset();
}
function setLabel($label) {
BCGBarcode1D::setLabel($label);
$this->setLabelOffset();
}
function setOffsetY($offsetY) {
BCGBarcode1D::setOffsetY($offsetY);
$this->setLabelOffset();
}
function setScale($scale) {
BCGBarcode1D::setScale($scale);
$this->setLabelOffset();
}
/**
* Draws the barcode
*
* @param resource $im
*/
function draw(&$im) {
$error_stop = false;
// Checking if all chars are allowed
$c = strlen($this->text);
for($i = 0; $i < $c; $i++) {
if(array_search($this->text[$i], $this->keys) === false) {
$this->drawError($im, 'Char \'' . $this->text[$i] . '\' not allowed.');
$error_stop = true;
}
}
if($error_stop === false) {
// Must contain 5 chars
if($c !== 5) {
$this->drawError($im, 'Must contain 5 chars.');
$error_stop = true;
}
if($error_stop === false) {
// Checksum
$this->calculateChecksum();
// Starting Code
$this->drawChar($im, '001', true);
// Code
for($i = 0; $i < 5; $i++) {
$this->drawChar($im, BCGupcext5::inverse($this->findCode($this->text[$i]), $this->codeParity[$this->checksumValue][$i]), false);
if($i < 4) {
$this->drawChar($im, '00', false); // Inter-char
}
}
$this->drawText($im);
}
}
}
/**
* Returns the maximal size of a barcode
*
* @return int[]
*/
function getMaxSize() {
$p = BCGBarcode1D::getMaxSize();
$startlength = 4 * $this->scale;
$textlength = 5 * 7 * $this->scale;
$intercharlength = 2 * 4 * $this->scale;
$label = $this->getLabel();
$textHeight = 0;
if(!empty($label)) {
if(is_a($this->textfont, 'BCGFont')) {
$textfont = $this->textfont; // clone
$textfont->setText($label);
$textHeight = $textfont->getHeight() + $this->SIZE_SPACING_FONT;
} elseif($this->textfont !== 0) {
$textHeight = imagefontheight($this->textfont) + $this->SIZE_SPACING_FONT;
}
}
return array($p[0] + $startlength + $textlength + $intercharlength, $p[1] - $textHeight);
}
/**
* Overloaded method to calculate checksum
*/
function calculateChecksum() {
// Calculating Checksum
// Consider the right-most digit of the message to be in an "odd" position,
// and assign odd/even to each character moving from right to left
// Odd Position = 3, Even Position = 9
// Multiply it by the number
// Add all of that and do ?mod10
$odd = true;
$this->checksumValue = 0;
$c = strlen($this->text);
for($i = $c; $i > 0; $i--) {
if($odd === true) {
$multiplier = 3;
$odd = false;
} else {
$multiplier = 9;
$odd = true;
}
if(!isset($this->keys[$this->text[$i - 1]])) {
return;
}
$this->checksumValue += $this->keys[$this->text[$i - 1]] * $multiplier;
}
$this->checksumValue = $this->checksumValue % 10;
}
/**
* Overloaded method to display the checksum
*/
function processChecksum() {
if($this->checksumValue === false) { // Calculate the checksum only once
$this->calculateChecksum();
}
if($this->checksumValue !== false) {
return $this->keys[$this->checksumValue];
}
return false;
}
/**
* Overloaded method for drawing special label
*
* @param resource $im
*/
function drawText(&$im) {
$label = $this->getLabel();
if(!empty($label)) {
$pA = $this->getMaxSize();
$pB = BCGBarcode1D::getMaxSize();
$w = $pA[0] - $pB[0];
if(is_a($this->textfont, 'BCGFont')) {
$textfont = $this->textfont; // clone
$textfont->setText($label);
$xPosition = ($w / 2) - ($textfont->getWidth() / 2) + $this->offsetX * $this->scale;
$yPosition = $this->offsetY * $this->scale - $this->SIZE_SPACING_FONT;
$textfont->draw($im, $this->colorFg->allocate($im), $xPosition, $yPosition);
} elseif($this->textfont !== 0) {
$xPosition = ($w / 2) - (strlen($label) / 2) * imagefontwidth($this->textfont) + $this->offsetX * $this->scale;
$yPosition = $this->offsetY * $this->scale - $this->SIZE_SPACING_FONT - imagefontheight($this->textfont);
imagestring($im, $this->textfont, $xPosition, $yPosition, $label, $this->colorFg->allocate($im));
}
}
}
function setLabelOffset() {
$label = $this->getLabel();
if(!empty($label)) {
if(is_a($this->textfont, 'BCGFont')) {
$f = $this->textfont; // clone
$f->setText($label);
$val = ($f->getHeight() - $f->getUnderBaseline()) / $this->scale + $this->SIZE_SPACING_FONT;
if($val > $this->offsetY) {
$this->offsetY = $val;
}
} elseif($this->textfont !== 0) {
$val = (imagefontheight($this->textfont) + 2) / $this->scale;
if($val > $this->offsetY) {
$this->offsetY = $val;
}
}
}
}
function inverse($text, $inverse = 1) { // static
if($inverse === 1) {
$text = strrev($text);
}
return $text;
}
};
?>

View File

@@ -0,0 +1,48 @@
<?php
/**
* JoinDraw.php
*--------------------------------------------------------------------
*
* Enable to join 2 BCGDrawing or 2 image object to make only one image.
* There are some options for alignement.
*
* ! THIS CLASS IS NOT AVAILABLE FOR PHP4 !
*
*--------------------------------------------------------------------
* Revision History
* v2.0.1 09 mar 2009 Jean-Sébastien Goupil Update for BCG classes
* v1.2.3b 31 dec 2005 Jean-Sébastien Goupil
*--------------------------------------------------------------------
* $Id: JoinDraw.php,v 1.4 2009/03/08 23:12:27 jsgoupil Exp $
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
class JoinDraw {
/**
* Construct the JoinDrawing Object.
* - $image1 and $image2 have to be BCGDrawing object or image object.
* - $space is the space between the two graphics in pixel.
* - $position is the position of the $image2 depending the $image1.
* - $alignment is the alignment of the $image2 if this one is smaller than $image1;
* if $image2 is bigger than $image1, the $image1 will be positionned on the opposite side specified.
*
* @param mixed $image1
* @param mixed $image2
* @param BCGColor $background
* @param int space
* @param int $position
* @param int $alignment
*/
function JoinDraw(&$image1, &$image2, $background, $space = 10, $position = 0, $alignment = 0) {
}
/**
* Returns the new $im created.
*
* @return resource
*/
function get_im() {
return false;
}
}

View File

@@ -0,0 +1,45 @@
<?php
/**
* BCGDraw.php
*--------------------------------------------------------------------
*
* Base class to draw images
*
*--------------------------------------------------------------------
* Revision History
* v2.1.0 8 nov 2009 Jean-Sébastien Goupil
*--------------------------------------------------------------------
* $Id: BCGDraw.php,v 1.1 2009/11/09 04:15:10 jsgoupil Exp $
* PHP5-Revision: 1.1
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
class BCGDraw { // abstract
var $im;
var $filename;
/**
* Constructor
*
* @param resource $im
*/
function BCGDraw(&$im) {
$this->im = $im;
}
/**
* Sets the filename
*
* @param string $filename
*/
function setFilename($filename) {
$this->filename = $filename;
}
/**
* Method needed to draw the image based on its specification (JPG, GIF, etc.)
*/
function draw() {} // abstract public
}
?>

View File

@@ -0,0 +1,109 @@
<?php
/**
* BCGDrawJPG.php
*--------------------------------------------------------------------
*
* Image Class to draw JPG images with possibility to set DPI
*
*--------------------------------------------------------------------
* Revision History
* v2.1.0 8 nov 2009 Jean-Sébastien Goupil
*--------------------------------------------------------------------
* $Id: BCGDrawJPG.php,v 1.1 2009/11/09 04:15:10 jsgoupil Exp $
* PHP5-Revision: 1.1
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGDraw.php');
if (!function_exists('file_put_contents')) {
function file_put_contents($filename, $data) {
$f = @fopen($filename, 'w');
if (!$f) {
return false;
} else {
$bytes = fwrite($f, $data);
fclose($f);
return $bytes;
}
}
}
class BCGDrawJPG extends BCGDraw {
var $dpi;
var $quality;
/**
* Constructor
*
* @param resource $im
*/
function BCGDrawJPG(&$im) {
BCGDraw::BCGDraw($im);
}
/**
* Sets the DPI
*
* @param int $dpi
*/
function setDPI($dpi) {
if(is_int($dpi)) {
$this->dpi = max(1, $dpi);
} else {
$this->dpi = null;
}
}
/**
* Sets the quality of the JPG
*
* @param int $quality
*/
function setQuality($quality) {
$this->quality = $quality;
}
/**
* Draws the JPG on the screen or in a file
*/
function draw() {
ob_start();
imagejpeg($this->im, null, $this->quality);
$bin = ob_get_contents();
ob_end_clean();
$this->setInternalProperties($bin);
if (empty($this->filename)) {
echo $bin;
} else {
file_put_contents($this->filename, $bin);
}
}
function setInternalProperties(&$bin) { // private
$this->internalSetDPI($bin);
$this->internalSetC($bin);
}
function internalSetDPI(&$bin) { // private
if($this->dpi !== null) {
$bin = substr_replace($bin, pack("Cnn", 0x01, $this->dpi, $this->dpi), 13, 5);
}
}
function internalSetC(&$bin) { // private
if(strcmp(substr($bin, 0, 4), pack('H*', 'FFD8FFE0')) === 0) {
$offset = 4 + (ord($bin[4]) << 8 | ord($bin[5]));
$firstPart = substr($bin, 0, $offset);
$secondPart = substr($bin, $offset);
$cr = pack('H*', 'FFFE004447656E657261746564207769746820426172636F64652047656E657261746F7220666F722050485020687474703A2F2F7777772E626172636F64657068702E636F6D');
$bin = $firstPart;
$bin .= $cr;
$bin .= $secondPart;
}
}
}
?>

View File

@@ -0,0 +1,209 @@
<?php
/**
* BCGDrawPNG.php
*--------------------------------------------------------------------
*
* Image Class to draw PNG images with possibility to set DPI
*
*--------------------------------------------------------------------
* Revision History
* v2.1.0 8 nov 2009 Jean-Sébastien Goupil
*--------------------------------------------------------------------
* $Id: BCGDrawPNG.php,v 1.1 2009/11/09 04:15:10 jsgoupil Exp $
* PHP5-Revision: 1.1
*--------------------------------------------------------------------
* Copyright (C) Jean-Sebastien Goupil
* http://www.barcodephp.com
*/
include_once('BCGDraw.php');
if (!function_exists('file_put_contents')) {
function file_put_contents($filename, $data) {
$f = @fopen($filename, 'w');
if (!$f) {
return false;
} else {
$bytes = fwrite($f, $data);
fclose($f);
return $bytes;
}
}
}
class BCGDrawPNG extends BCGDraw {
var $dpi;
/**
* Constructor
*
* @param resource $im
*/
function BCGDrawPNG(&$im) {
BCGDraw::BCGDraw($im);
}
/**
* Sets the DPI
*
* @param int $dpi
*/
function setDPI($dpi) {
if(is_numeric($dpi)) {
$this->dpi = max(1, $dpi);
} else {
$this->dpi = null;
}
}
/**
* Draws the PNG on the screen or in a file
*/
function draw() {
ob_start();
imagepng($this->im);
$bin = ob_get_contents();
ob_end_clean();
$this->setInternalProperties($bin);
if (empty($this->filename)) {
echo $bin;
} else {
file_put_contents($this->filename, $bin);
}
}
function setInternalProperties(&$bin) { // private
// Scan all the ChunkType
if(strcmp(substr($bin, 0, 8), pack('H*', '89504E470D0A1A0A')) === 0) {
$chunks = $this->detectChunks($bin);
$this->internalSetDPI($bin, $chunks);
$this->internalSetC($bin, $chunks);
}
}
function detectChunks($bin) { // private
$data = substr($bin, 8);
$chunks = array();
$c = strlen($data);
$offset = 0;
while($offset < $c) {
$packed = unpack('Nsize/a4chunk', $data);
$size = $packed['size'];
$chunk = $packed['chunk'];
$chunks[] = array('offset'=>$offset + 8, 'size'=>$size, 'chunk'=>$chunk);
$jump = $size + 12;
$offset += $jump;
$data = substr($data, $jump);
}
return $chunks;
}
function internalSetDPI(&$bin, &$chunks) { // private
if($this->dpi !== null) {
$meters = (int)($this->dpi * 39.37007874);
$found = -1;
$c = count($chunks);
for($i = 0; $i < $c; $i++) {
// We already have a pHYs
if($chunks[$i]['chunk'] === 'pHYs') {
$found = $i;
break;
}
}
$data = 'pHYs' . pack('NNC', $meters, $meters, 0x01);
$crc = BCGDrawPNG::crc($data, 13);
$cr = pack('Na13N', 9, $data, $crc);
// We didn't have a pHYs
if($found == -1) {
// Don't do anything if we have a bad PNG
if($c >= 2 && $chunk[0]['chunk'] = 'IHDR') {
array_splice($chunks, 1, 0, array(array('offset'=>33, 'size'=>9, 'chunk'=>'pHYs')));
// Push the data
for($i = 2; $i < $c; $i++) {
$chunks[$i]['offset'] += 21;
}
$firstPart = substr($bin, 0, 33);
$secondPart = substr($bin, 33);
$bin = $firstPart;
$bin .= $cr;
$bin .= $secondPart;
}
} else {
$bin = substr_replace($bin, $cr, $chunks[$i]['offset'], 21);
}
}
}
function internalSetC(&$bin, &$chunks) { // private
if(count($chunks) >= 2 && $chunk[0]['chunk'] = 'IHDR') {
$firstPart = substr($bin, 0, 33);
$secondPart = substr($bin, 33);
$cr = pack('H*', '0000004C74455874436F707972696768740047656E657261746564207769746820426172636F64652047656E657261746F7220666F722050485020687474703A2F2F7777772E626172636F64657068702E636F6D597F70B8');
$bin = $firstPart;
$bin .= $cr;
$bin .= $secondPart;
}
// Chunks is dirty!! But we are done.
}
var $crc_table = array();
var $crc_table_computed = false;
function make_crc_table() { // private static
for($n = 0; $n < 256; $n++) {
$c = $n;
for ($k = 0; $k < 8; $k++) {
if (($c & 1) == 1) {
$c = 0xedb88320 ^ (BCGDrawPNG::SHR($c, 1));
} else {
$c = BCGDrawPNG::SHR($c, 1);
}
}
$this->crc_table[$n] = $c;
}
$this->crc_table_computed = true;
}
function SHR($x, $n) { // private static
$mask = 0x40000000;
if ($x < 0) {
$x &= 0x7FFFFFFF;
$mask = $mask >> ($n - 1);
return ($x >> $n) | $mask;
}
return (int)$x >> (int)$n;
}
function update_crc($crc, $buf, $len) { // private static
$c = $crc;
if (!$this->crc_table_computed) {
BCGDrawPNG::make_crc_table();
}
for($n = 0; $n < $len; $n++) {
$c = $this->crc_table[($c ^ ord($buf[$n])) & 0xff] ^ (BCGDrawPNG::SHR($c, 8));
}
return $c;
}
function crc($data, $len) { // private static
return BCGDrawPNG::update_crc(-1, $data, $len) ^ -1;
}
}
?>

Binary file not shown.