";
+ return $display_table;
+ }
+
+ private function manage_display_layout($layout_type, $item, $barcode_config)
+ {
+ $result;
+ if($layout_type == 'item_code')
+ {
+ $result = "CI->Appconfig->get('barcode_type').
+ "' onerror=\"(function(pThis){pThis.onerror = null; pThis.src = pThis.src;})(this)\" />";
+ }
+ else if($layout_type == 'name'){
+ $result = $this->CI->lang->line('items_name') . " " . $item['name'];
+ }
+ else if($layout_type == 'category'){
+ $result = $this->CI->lang->line('items_category') . " " . $item['category'];
+ }
+ else if($layout_type == 'cost_price'){
+ $result = $this->CI->lang->line('items_cost_price') . " " . to_currency($item['cost_price']);
+ }
+ else if($layout_type == 'unit_price'){
+ $result = $this->CI->lang->line('items_unit_price') . " " . to_currency($item['unit_price']);
+ }
+ return $result;
+ }
+
+ function get_font_name($font_file_name)
+ {
+ return substr($font_file_name, 0, -4);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/README_1D.txt b/application/libraries/barcodegen/README_1D.txt
new file mode 100644
index 000000000..78e653e74
--- /dev/null
+++ b/application/libraries/barcodegen/README_1D.txt
@@ -0,0 +1,48 @@
+This script is free for personal use. The program is provide "AS IS"
+without warranty of any kind. If you want to use it as
+commercial use, you have to purchase it on
+http://www.barcodephp.com
+You must let the copyright intact.
+
+Ce script est gratuit pour usage personnel. Le programme est
+fourni "TEL QUEL" sans aucune garantie que ce soit.
+Si vous voulez l'utiliser pour un usage commercial,
+vous devez l'acheter sur
+http://www.barcodephp.com
+Vous devez laisser les droits d'auteur intacts.
+This script is free for personal use. The program is provide "AS IS"
+without warranty of any kind. If you want to use it as
+commercial use, you have to purchase it on
+http://www.barcodephp.com
+You must let the copyright intact.
+
+Ce script est gratuit pour usage personnel. Le programme est
+fourni "TEL QUEL" sans aucune garantie que ce soit.
+Si vous voulez l'utiliser pour un usage commercial,
+vous devez l'acheter sur
+http://www.barcodephp.com
+Vous devez laisser les droits d'auteur intacts.
+This script is free for personal use. The program is provide "AS IS"
+without warranty of any kind. If you want to use it as
+commercial use, you have to purchase it on
+http://www.barcodephp.com
+You must let the copyright intact.
+
+Ce script est gratuit pour usage personnel. Le programme est
+fourni "TEL QUEL" sans aucune garantie que ce soit.
+Si vous voulez l'utiliser pour un usage commercial,
+vous devez l'acheter sur
+http://www.barcodephp.com
+Vous devez laisser les droits d'auteur intacts.
+This script is free for personal use. The program is provide "AS IS"
+without warranty of any kind. If you want to use it as
+commercial use, you have to purchase it on
+http://www.barcodephp.com
+You must let the copyright intact.
+
+Ce script est gratuit pour usage personnel. Le programme est
+fourni "TEL QUEL" sans aucune garantie que ce soit.
+Si vous voulez l'utiliser pour un usage commercial,
+vous devez l'acheter sur
+http://www.barcodephp.com
+Vous devez laisser les droits d'auteur intacts.
\ No newline at end of file
diff --git a/application/libraries/barcodegen/VERSION_1D b/application/libraries/barcodegen/VERSION_1D
new file mode 100644
index 000000000..4f6b77e0b
--- /dev/null
+++ b/application/libraries/barcodegen/VERSION_1D
@@ -0,0 +1,412 @@
+v5.2.0 26 may 2014 Fix potential break in PNG writter.
+ Fix BCGColor. Deprecated usage of string character reference.
+ Rotation of text or barcode is now CLOCKWISE.
+ Fix Code11. Incorrect size when using a scale bigger than 1.
+ Fix Code128. Potential incorrect table lookup.
+ Fix IntelligentMail user interface not accepting correct serial number.
+ Improve speed by setting some methods static.
+ Fix OtherCode. It now checks for incorrect input.
+ Use ISO-8859-1 when generating a barcode with the user interface.
+ Usage of quotes and double quotes was not working properly with the user interface.
+v5.1.0 4 oct 2012 Files moved to support 1D and 2D barcodes together
+ Whiskers has been removed from writing a small line in scale 1 (bug in PHP)
+ Add alignDefaultLabel for EAN-13 and UPC-A
+ Versioning is now per file
+ BoxFix can now be overriden
+ Fix some references
+v5.0.1 18 apr 2012 Fix Navigation support
+v5.0.0 18 apr 2012 HTML5 support. Fix some exception file inclusion bugs.
+ Using space instead of tabs! Added support to change the boxfix.
+ Added support to Intelligent Mail. Better support for Postnet. Following standard for printing.
+ Added getters in GS1-128.
+v4.1.0 3 aug 2011 Support for transparent background
+v4.0.0 15 apr 2011 Brand new version which includes some breaking changes.
+ Now supports the possibility to add labels around the barcode really easily thanks to the method addLabel()
+ You can also specify the alignment of the label, rotation, etc.
+ If the label is bigger than the barcode itself, the image will get bigger to avoid text clipping.
+ Add the setRatio method for I25 barcodes
+ Fix EAN-13 and ISBN
+v3.0.2 4 apr 2011 Fixing the test.php
+v3.0.1 26 mar 2011 Minor fixes for IE9
+v3.0.0 21 mar 2011 Better support for failure instead of writing the error on the UI, an exception is being thrown.
+v2.2.0 13 feb 2010 Added the support for GS1-128 (EAN-128).
+ Fix ISBN text support to be the right font.
+ Make sure the /html files are formatted.
+v2.1.0 8 nov 2009 Added a way to change the DPI before saving (BCGDrawing::setDPI()). Set the value to null if you want to improve the performance and still have 72dpi.
+ But you can set it to 300 if you wish to print it.
+ You do not need an additional DLL for this.
+ Added a way to rotate in degree the barcode before saving (BCGDrawing::setRotationAngle()).
+ Added a verification if you have GD installed... So that way you know it before contacting support :)
+ Fix HTML display for Code 93 and Code 39 Extended buttons
+ You can now specify a specific table for Code 128. For instance, if you want to force to use the table B, you would write the following to parse
+ array(CODE128_B, 'The Text To Encode')
+ The default table selection for Code 128 is automatically chosen.
+ Fix many PHP4 errors.
+v2.0.1Fix 28 jul 2009 Change UPC-E encoding from UTF-8 to ANSI
+v2.0.1 21 may 2009 Fix the Code 128C, Fix EAN-8, EAN-13, UPC-A, UPC-E and Postnet padding, MSI checksum can be 1 or 2
+ Fix JoinDraw class
+ Added GIF and WBMP support
+ Fix the Checksum Text displayed for ISBN
+ Fix padding for ISBN with setOffsetY
+ Fix Button in /html for IE8
+v2.0.0 23 apr 2008 The new version has been released... All the codes have been revamped to fit with
+ common file for 2D barcodes. Instead of using "setText()" method, the method
+ parse() is used.
+ Thickness is modified by the scale.
+ Code 128: it has been modified completely, no need to specify which encoding you want to
+ use, it will select it for you automatically and try to get the shortest barcode.
+ Codabar: you can't only put one letter as a barcode.
+ Code 93: supports now the extended full ASCII 0 to 127
+ Code 39 extended has been added in a separate file since the extended
+ version of Code 39 is totally optional.
+ Codabar has been fixed for B and C letter
+ We got our real nice domain: http://www.barcodephp.com
+v1.3.0 13 apr 2007 Remove ISBN from EAN-13 and a new file has been created to handle
+ ISBN-10 and ISBN-13.
+v1.2.4 1 feb 2007 Fix Code128. There were some errors dealing with C table
+v1.2.3pl1 11 mar 2006 Correct the EAN-13/ISBN file. There was a problem with displaying correctly an ISBN.
+v1.2.3 8 feb 2006 Int for font is no longer deprecated and can be used.
+ Correct many labels' positions : ean8, ean13, upca, upce
+ Correct getWidth of Font.
+v1.2.3b 5 jan 2006 Add separate checksum method to calculate and get this special number created and a way to display it with the label.
+ Correct code for PHP5.1 compatibility. Selecting a char by { } is now deprecated. Using of [ ] is used instead.
+ Correct checksum for Code11. In some case, the checksum was bad.
+ Correct problem displaying label with text under the baseline (letters such as p, g...).
+ SIZE_SPACING_FONT_END has been suppressed since the previous bug has been fixed.
+ Correct label if two barcode were generated with the same font. The font is now cloned immediately before using.
+ The FDrawing has new methods now, use setBarcode and draw instead of add_barcode and draw_all. Only one barcode per FDrawing is possible now.
+ Correct errors of othercode if no text font has been selected.
+ othercode was not working for PHP4 due to the lack of the str_split function. Now the function is emulated.
+ New file : JoinDraw allows you to join 2 graphic and align each of them. (Useful for UCPExt). PHP5 only
+ Currently Working on UPC-A label
+v1.2.2 23 jul 2005 Correct checksum for i25 and s25 barcode (thanks to Gerald Pienkowski (Germany))
+ Enhance rapidity for some barcode
+ Change almost all comment in files : the update 1.2.1 was in 2005, not in 2004 ;)
+v1.2.1 27 jun 2005 The php code is now cleaner :)
+ Increase rapidity of execution
+ Type verifications in conditions
+ NEW support of exterior font (Arial, Courier, etc.) with a size that you can specify
+ Use PHP fonts is deprecated and they will be deleted in further versions.
+ Remove the "alt" text on the image (IE displays it as a tooltip)
+ Color class has been enhanced and accept new parameter for constructor
+ Now you don't have to provide a specific size of the image, it will be calculated automatically for barcodes and errors
+ Added the version number at the bottom of the script html.
+ Correcting code 128 to output code correctly when passing from code C to another code
+v1.05 27 jun 2005 UPCext2 has been corrected. It could display a wrong barcode.
+ Correcting UPC-A, bad output when writting text
+v1.04 2 apr 2005 Correcting some bugs and makes available for commercial usage : purchase it on http://www.barcodephp.com
+v1.03 28 mar 2005 Correcting DrawChar
+v1.02 8 mar 2005 Transforming PHPDOC and converting to XHTML1.0 Transitionnal
+ And adding a special option that check if you have PHP5 installed
+ Because to many people are writing to me that saying the script doesn't work (because they have PHP4).
+v1.01 7 jul 2004 Correcting code39.barcode.php
+v1.00 17 jun 2004 New :)
+v5.2.0 26 may 2014 Fix potential break in PNG writter.
+ Fix BCGColor. Deprecated usage of string character reference.
+ Rotation of text or barcode is now CLOCKWISE.
+ Fix Code11. Incorrect size when using a scale bigger than 1.
+ Fix Code128. Potential incorrect table lookup.
+ Fix IntelligentMail user interface not accepting correct serial number.
+ Improve speed by setting some methods static.
+ Fix OtherCode. It now checks for incorrect input.
+ Use ISO-8859-1 when generating a barcode with the user interface.
+ Usage of quotes and double quotes was not working properly with the user interface.
+v5.1.0 4 oct 2012 Files moved to support 1D and 2D barcodes together
+ Whiskers has been removed from writing a small line in scale 1 (bug in PHP)
+ Add alignDefaultLabel for EAN-13 and UPC-A
+ Versioning is now per file
+ BoxFix can now be overriden
+ Fix some references
+v5.0.1 18 apr 2012 Fix Navigation support
+v5.0.0 18 apr 2012 HTML5 support. Fix some exception file inclusion bugs.
+ Using space instead of tabs! Added support to change the boxfix.
+ Added support to Intelligent Mail. Better support for Postnet. Following standard for printing.
+ Added getters in GS1-128.
+v4.1.0 3 aug 2011 Support for transparent background
+v4.0.0 15 apr 2011 Brand new version which includes some breaking changes.
+ Now supports the possibility to add labels around the barcode really easily thanks to the method addLabel()
+ You can also specify the alignment of the label, rotation, etc.
+ If the label is bigger than the barcode itself, the image will get bigger to avoid text clipping.
+ Add the setRatio method for I25 barcodes
+ Fix EAN-13 and ISBN
+v3.0.2 4 apr 2011 Fixing the test.php
+v3.0.1 26 mar 2011 Minor fixes for IE9
+v3.0.0 21 mar 2011 Better support for failure instead of writing the error on the UI, an exception is being thrown.
+v2.2.0 13 feb 2010 Added the support for GS1-128 (EAN-128).
+ Fix ISBN text support to be the right font.
+ Make sure the /html files are formatted.
+v2.1.0 8 nov 2009 Added a way to change the DPI before saving (BCGDrawing::setDPI()). Set the value to null if you want to improve the performance and still have 72dpi.
+ But you can set it to 300 if you wish to print it.
+ You do not need an additional DLL for this.
+ Added a way to rotate in degree the barcode before saving (BCGDrawing::setRotationAngle()).
+ Added a verification if you have GD installed... So that way you know it before contacting support :)
+ Fix HTML display for Code 93 and Code 39 Extended buttons
+ You can now specify a specific table for Code 128. For instance, if you want to force to use the table B, you would write the following to parse
+ array(CODE128_B, 'The Text To Encode')
+ The default table selection for Code 128 is automatically chosen.
+ Fix many PHP4 errors.
+v2.0.1Fix 28 jul 2009 Change UPC-E encoding from UTF-8 to ANSI
+v2.0.1 21 may 2009 Fix the Code 128C, Fix EAN-8, EAN-13, UPC-A, UPC-E and Postnet padding, MSI checksum can be 1 or 2
+ Fix JoinDraw class
+ Added GIF and WBMP support
+ Fix the Checksum Text displayed for ISBN
+ Fix padding for ISBN with setOffsetY
+ Fix Button in /html for IE8
+v2.0.0 23 apr 2008 The new version has been released... All the codes have been revamped to fit with
+ common file for 2D barcodes. Instead of using "setText()" method, the method
+ parse() is used.
+ Thickness is modified by the scale.
+ Code 128: it has been modified completely, no need to specify which encoding you want to
+ use, it will select it for you automatically and try to get the shortest barcode.
+ Codabar: you can't only put one letter as a barcode.
+ Code 93: supports now the extended full ASCII 0 to 127
+ Code 39 extended has been added in a separate file since the extended
+ version of Code 39 is totally optional.
+ Codabar has been fixed for B and C letter
+ We got our real nice domain: http://www.barcodephp.com
+v1.3.0 13 apr 2007 Remove ISBN from EAN-13 and a new file has been created to handle
+ ISBN-10 and ISBN-13.
+v1.2.4 1 feb 2007 Fix Code128. There were some errors dealing with C table
+v1.2.3pl1 11 mar 2006 Correct the EAN-13/ISBN file. There was a problem with displaying correctly an ISBN.
+v1.2.3 8 feb 2006 Int for font is no longer deprecated and can be used.
+ Correct many labels' positions : ean8, ean13, upca, upce
+ Correct getWidth of Font.
+v1.2.3b 5 jan 2006 Add separate checksum method to calculate and get this special number created and a way to display it with the label.
+ Correct code for PHP5.1 compatibility. Selecting a char by { } is now deprecated. Using of [ ] is used instead.
+ Correct checksum for Code11. In some case, the checksum was bad.
+ Correct problem displaying label with text under the baseline (letters such as p, g...).
+ SIZE_SPACING_FONT_END has been suppressed since the previous bug has been fixed.
+ Correct label if two barcode were generated with the same font. The font is now cloned immediately before using.
+ The FDrawing has new methods now, use setBarcode and draw instead of add_barcode and draw_all. Only one barcode per FDrawing is possible now.
+ Correct errors of othercode if no text font has been selected.
+ othercode was not working for PHP4 due to the lack of the str_split function. Now the function is emulated.
+ New file : JoinDraw allows you to join 2 graphic and align each of them. (Useful for UCPExt). PHP5 only
+ Currently Working on UPC-A label
+v1.2.2 23 jul 2005 Correct checksum for i25 and s25 barcode (thanks to Gerald Pienkowski (Germany))
+ Enhance rapidity for some barcode
+ Change almost all comment in files : the update 1.2.1 was in 2005, not in 2004 ;)
+v1.2.1 27 jun 2005 The php code is now cleaner :)
+ Increase rapidity of execution
+ Type verifications in conditions
+ NEW support of exterior font (Arial, Courier, etc.) with a size that you can specify
+ Use PHP fonts is deprecated and they will be deleted in further versions.
+ Remove the "alt" text on the image (IE displays it as a tooltip)
+ Color class has been enhanced and accept new parameter for constructor
+ Now you don't have to provide a specific size of the image, it will be calculated automatically for barcodes and errors
+ Added the version number at the bottom of the script html.
+ Correcting code 128 to output code correctly when passing from code C to another code
+v1.05 27 jun 2005 UPCext2 has been corrected. It could display a wrong barcode.
+ Correcting UPC-A, bad output when writting text
+v1.04 2 apr 2005 Correcting some bugs and makes available for commercial usage : purchase it on http://www.barcodephp.com
+v1.03 28 mar 2005 Correcting DrawChar
+v1.02 8 mar 2005 Transforming PHPDOC and converting to XHTML1.0 Transitionnal
+ And adding a special option that check if you have PHP5 installed
+ Because to many people are writing to me that saying the script doesn't work (because they have PHP4).
+v1.01 7 jul 2004 Correcting code39.barcode.php
+v1.00 17 jun 2004 New :)
+v5.2.0 26 may 2014 Fix potential break in PNG writter.
+ Fix BCGColor. Deprecated usage of string character reference.
+ Rotation of text or barcode is now CLOCKWISE.
+ Fix Code11. Incorrect size when using a scale bigger than 1.
+ Fix Code128. Potential incorrect table lookup.
+ Fix IntelligentMail user interface not accepting correct serial number.
+ Improve speed by setting some methods static.
+ Fix OtherCode. It now checks for incorrect input.
+ Use ISO-8859-1 when generating a barcode with the user interface.
+ Usage of quotes and double quotes was not working properly with the user interface.
+v5.1.0 4 oct 2012 Files moved to support 1D and 2D barcodes together
+ Whiskers has been removed from writing a small line in scale 1 (bug in PHP)
+ Add alignDefaultLabel for EAN-13 and UPC-A
+ Versioning is now per file
+ BoxFix can now be overriden
+ Fix some references
+v5.0.1 18 apr 2012 Fix Navigation support
+v5.0.0 18 apr 2012 HTML5 support. Fix some exception file inclusion bugs.
+ Using space instead of tabs! Added support to change the boxfix.
+ Added support to Intelligent Mail. Better support for Postnet. Following standard for printing.
+ Added getters in GS1-128.
+v4.1.0 3 aug 2011 Support for transparent background
+v4.0.0 15 apr 2011 Brand new version which includes some breaking changes.
+ Now supports the possibility to add labels around the barcode really easily thanks to the method addLabel()
+ You can also specify the alignment of the label, rotation, etc.
+ If the label is bigger than the barcode itself, the image will get bigger to avoid text clipping.
+ Add the setRatio method for I25 barcodes
+ Fix EAN-13 and ISBN
+v3.0.2 4 apr 2011 Fixing the test.php
+v3.0.1 26 mar 2011 Minor fixes for IE9
+v3.0.0 21 mar 2011 Better support for failure instead of writing the error on the UI, an exception is being thrown.
+v2.2.0 13 feb 2010 Added the support for GS1-128 (EAN-128).
+ Fix ISBN text support to be the right font.
+ Make sure the /html files are formatted.
+v2.1.0 8 nov 2009 Added a way to change the DPI before saving (BCGDrawing::setDPI()). Set the value to null if you want to improve the performance and still have 72dpi.
+ But you can set it to 300 if you wish to print it.
+ You do not need an additional DLL for this.
+ Added a way to rotate in degree the barcode before saving (BCGDrawing::setRotationAngle()).
+ Added a verification if you have GD installed... So that way you know it before contacting support :)
+ Fix HTML display for Code 93 and Code 39 Extended buttons
+ You can now specify a specific table for Code 128. For instance, if you want to force to use the table B, you would write the following to parse
+ array(CODE128_B, 'The Text To Encode')
+ The default table selection for Code 128 is automatically chosen.
+ Fix many PHP4 errors.
+v2.0.1Fix 28 jul 2009 Change UPC-E encoding from UTF-8 to ANSI
+v2.0.1 21 may 2009 Fix the Code 128C, Fix EAN-8, EAN-13, UPC-A, UPC-E and Postnet padding, MSI checksum can be 1 or 2
+ Fix JoinDraw class
+ Added GIF and WBMP support
+ Fix the Checksum Text displayed for ISBN
+ Fix padding for ISBN with setOffsetY
+ Fix Button in /html for IE8
+v2.0.0 23 apr 2008 The new version has been released... All the codes have been revamped to fit with
+ common file for 2D barcodes. Instead of using "setText()" method, the method
+ parse() is used.
+ Thickness is modified by the scale.
+ Code 128: it has been modified completely, no need to specify which encoding you want to
+ use, it will select it for you automatically and try to get the shortest barcode.
+ Codabar: you can't only put one letter as a barcode.
+ Code 93: supports now the extended full ASCII 0 to 127
+ Code 39 extended has been added in a separate file since the extended
+ version of Code 39 is totally optional.
+ Codabar has been fixed for B and C letter
+ We got our real nice domain: http://www.barcodephp.com
+v1.3.0 13 apr 2007 Remove ISBN from EAN-13 and a new file has been created to handle
+ ISBN-10 and ISBN-13.
+v1.2.4 1 feb 2007 Fix Code128. There were some errors dealing with C table
+v1.2.3pl1 11 mar 2006 Correct the EAN-13/ISBN file. There was a problem with displaying correctly an ISBN.
+v1.2.3 8 feb 2006 Int for font is no longer deprecated and can be used.
+ Correct many labels' positions : ean8, ean13, upca, upce
+ Correct getWidth of Font.
+v1.2.3b 5 jan 2006 Add separate checksum method to calculate and get this special number created and a way to display it with the label.
+ Correct code for PHP5.1 compatibility. Selecting a char by { } is now deprecated. Using of [ ] is used instead.
+ Correct checksum for Code11. In some case, the checksum was bad.
+ Correct problem displaying label with text under the baseline (letters such as p, g...).
+ SIZE_SPACING_FONT_END has been suppressed since the previous bug has been fixed.
+ Correct label if two barcode were generated with the same font. The font is now cloned immediately before using.
+ The FDrawing has new methods now, use setBarcode and draw instead of add_barcode and draw_all. Only one barcode per FDrawing is possible now.
+ Correct errors of othercode if no text font has been selected.
+ othercode was not working for PHP4 due to the lack of the str_split function. Now the function is emulated.
+ New file : JoinDraw allows you to join 2 graphic and align each of them. (Useful for UCPExt). PHP5 only
+ Currently Working on UPC-A label
+v1.2.2 23 jul 2005 Correct checksum for i25 and s25 barcode (thanks to Gerald Pienkowski (Germany))
+ Enhance rapidity for some barcode
+ Change almost all comment in files : the update 1.2.1 was in 2005, not in 2004 ;)
+v1.2.1 27 jun 2005 The php code is now cleaner :)
+ Increase rapidity of execution
+ Type verifications in conditions
+ NEW support of exterior font (Arial, Courier, etc.) with a size that you can specify
+ Use PHP fonts is deprecated and they will be deleted in further versions.
+ Remove the "alt" text on the image (IE displays it as a tooltip)
+ Color class has been enhanced and accept new parameter for constructor
+ Now you don't have to provide a specific size of the image, it will be calculated automatically for barcodes and errors
+ Added the version number at the bottom of the script html.
+ Correcting code 128 to output code correctly when passing from code C to another code
+v1.05 27 jun 2005 UPCext2 has been corrected. It could display a wrong barcode.
+ Correcting UPC-A, bad output when writting text
+v1.04 2 apr 2005 Correcting some bugs and makes available for commercial usage : purchase it on http://www.barcodephp.com
+v1.03 28 mar 2005 Correcting DrawChar
+v1.02 8 mar 2005 Transforming PHPDOC and converting to XHTML1.0 Transitionnal
+ And adding a special option that check if you have PHP5 installed
+ Because to many people are writing to me that saying the script doesn't work (because they have PHP4).
+v1.01 7 jul 2004 Correcting code39.barcode.php
+v1.00 17 jun 2004 New :)
+v5.2.0 26 may 2014 Fix potential break in PNG writter.
+ Fix BCGColor. Deprecated usage of string character reference.
+ Rotation of text or barcode is now CLOCKWISE.
+ Fix Code11. Incorrect size when using a scale bigger than 1.
+ Fix Code128. Potential incorrect table lookup.
+ Fix IntelligentMail user interface not accepting correct serial number.
+ Improve speed by setting some methods static.
+ Fix OtherCode. It now checks for incorrect input.
+ Use ISO-8859-1 when generating a barcode with the user interface.
+ Usage of quotes and double quotes was not working properly with the user interface.
+v5.1.0 4 oct 2012 Files moved to support 1D and 2D barcodes together
+ Whiskers has been removed from writing a small line in scale 1 (bug in PHP)
+ Add alignDefaultLabel for EAN-13 and UPC-A
+ Versioning is now per file
+ BoxFix can now be overriden
+ Fix some references
+v5.0.1 18 apr 2012 Fix Navigation support
+v5.0.0 18 apr 2012 HTML5 support. Fix some exception file inclusion bugs.
+ Using space instead of tabs! Added support to change the boxfix.
+ Added support to Intelligent Mail. Better support for Postnet. Following standard for printing.
+ Added getters in GS1-128.
+v4.1.0 3 aug 2011 Support for transparent background
+v4.0.0 15 apr 2011 Brand new version which includes some breaking changes.
+ Now supports the possibility to add labels around the barcode really easily thanks to the method addLabel()
+ You can also specify the alignment of the label, rotation, etc.
+ If the label is bigger than the barcode itself, the image will get bigger to avoid text clipping.
+ Add the setRatio method for I25 barcodes
+ Fix EAN-13 and ISBN
+v3.0.2 4 apr 2011 Fixing the test.php
+v3.0.1 26 mar 2011 Minor fixes for IE9
+v3.0.0 21 mar 2011 Better support for failure instead of writing the error on the UI, an exception is being thrown.
+v2.2.0 13 feb 2010 Added the support for GS1-128 (EAN-128).
+ Fix ISBN text support to be the right font.
+ Make sure the /html files are formatted.
+v2.1.0 8 nov 2009 Added a way to change the DPI before saving (BCGDrawing::setDPI()). Set the value to null if you want to improve the performance and still have 72dpi.
+ But you can set it to 300 if you wish to print it.
+ You do not need an additional DLL for this.
+ Added a way to rotate in degree the barcode before saving (BCGDrawing::setRotationAngle()).
+ Added a verification if you have GD installed... So that way you know it before contacting support :)
+ Fix HTML display for Code 93 and Code 39 Extended buttons
+ You can now specify a specific table for Code 128. For instance, if you want to force to use the table B, you would write the following to parse
+ array(CODE128_B, 'The Text To Encode')
+ The default table selection for Code 128 is automatically chosen.
+ Fix many PHP4 errors.
+v2.0.1Fix 28 jul 2009 Change UPC-E encoding from UTF-8 to ANSI
+v2.0.1 21 may 2009 Fix the Code 128C, Fix EAN-8, EAN-13, UPC-A, UPC-E and Postnet padding, MSI checksum can be 1 or 2
+ Fix JoinDraw class
+ Added GIF and WBMP support
+ Fix the Checksum Text displayed for ISBN
+ Fix padding for ISBN with setOffsetY
+ Fix Button in /html for IE8
+v2.0.0 23 apr 2008 The new version has been released... All the codes have been revamped to fit with
+ common file for 2D barcodes. Instead of using "setText()" method, the method
+ parse() is used.
+ Thickness is modified by the scale.
+ Code 128: it has been modified completely, no need to specify which encoding you want to
+ use, it will select it for you automatically and try to get the shortest barcode.
+ Codabar: you can't only put one letter as a barcode.
+ Code 93: supports now the extended full ASCII 0 to 127
+ Code 39 extended has been added in a separate file since the extended
+ version of Code 39 is totally optional.
+ Codabar has been fixed for B and C letter
+ We got our real nice domain: http://www.barcodephp.com
+v1.3.0 13 apr 2007 Remove ISBN from EAN-13 and a new file has been created to handle
+ ISBN-10 and ISBN-13.
+v1.2.4 1 feb 2007 Fix Code128. There were some errors dealing with C table
+v1.2.3pl1 11 mar 2006 Correct the EAN-13/ISBN file. There was a problem with displaying correctly an ISBN.
+v1.2.3 8 feb 2006 Int for font is no longer deprecated and can be used.
+ Correct many labels' positions : ean8, ean13, upca, upce
+ Correct getWidth of Font.
+v1.2.3b 5 jan 2006 Add separate checksum method to calculate and get this special number created and a way to display it with the label.
+ Correct code for PHP5.1 compatibility. Selecting a char by { } is now deprecated. Using of [ ] is used instead.
+ Correct checksum for Code11. In some case, the checksum was bad.
+ Correct problem displaying label with text under the baseline (letters such as p, g...).
+ SIZE_SPACING_FONT_END has been suppressed since the previous bug has been fixed.
+ Correct label if two barcode were generated with the same font. The font is now cloned immediately before using.
+ The FDrawing has new methods now, use setBarcode and draw instead of add_barcode and draw_all. Only one barcode per FDrawing is possible now.
+ Correct errors of othercode if no text font has been selected.
+ othercode was not working for PHP4 due to the lack of the str_split function. Now the function is emulated.
+ New file : JoinDraw allows you to join 2 graphic and align each of them. (Useful for UCPExt). PHP5 only
+ Currently Working on UPC-A label
+v1.2.2 23 jul 2005 Correct checksum for i25 and s25 barcode (thanks to Gerald Pienkowski (Germany))
+ Enhance rapidity for some barcode
+ Change almost all comment in files : the update 1.2.1 was in 2005, not in 2004 ;)
+v1.2.1 27 jun 2005 The php code is now cleaner :)
+ Increase rapidity of execution
+ Type verifications in conditions
+ NEW support of exterior font (Arial, Courier, etc.) with a size that you can specify
+ Use PHP fonts is deprecated and they will be deleted in further versions.
+ Remove the "alt" text on the image (IE displays it as a tooltip)
+ Color class has been enhanced and accept new parameter for constructor
+ Now you don't have to provide a specific size of the image, it will be calculated automatically for barcodes and errors
+ Added the version number at the bottom of the script html.
+ Correcting code 128 to output code correctly when passing from code C to another code
+v1.05 27 jun 2005 UPCext2 has been corrected. It could display a wrong barcode.
+ Correcting UPC-A, bad output when writting text
+v1.04 2 apr 2005 Correcting some bugs and makes available for commercial usage : purchase it on http://www.barcodephp.com
+v1.03 28 mar 2005 Correcting DrawChar
+v1.02 8 mar 2005 Transforming PHPDOC and converting to XHTML1.0 Transitionnal
+ And adding a special option that check if you have PHP5 installed
+ Because to many people are writing to me that saying the script doesn't work (because they have PHP4).
+v1.01 7 jul 2004 Correcting code39.barcode.php
+v1.00 17 jun 2004 New :)
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGArgumentException.php b/application/libraries/barcodegen/class/BCGArgumentException.php
new file mode 100755
index 000000000..a0e98e795
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGArgumentException.php
@@ -0,0 +1,25 @@
+param = $param;
+ parent::__construct($message, 20000);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGBarcode.php b/application/libraries/barcodegen/class/BCGBarcode.php
new file mode 100755
index 000000000..66ea3e281
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGBarcode.php
@@ -0,0 +1,436 @@
+setOffsetX(0);
+ $this->setOffsetY(0);
+ $this->setForegroundColor(0x000000);
+ $this->setBackgroundColor(0xffffff);
+ $this->setScale(1);
+ }
+
+ /**
+ * Parses the text before displaying it.
+ *
+ * @param mixed $text
+ */
+ public function parse($text) {
+ }
+
+ /**
+ * Gets the foreground color of the barcode.
+ *
+ * @return BCGColor
+ */
+ public function getForegroundColor() {
+ return $this->colorFg;
+ }
+
+ /**
+ * 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
+ */
+ public function setForegroundColor($code) {
+ if ($code instanceof BCGColor) {
+ $this->colorFg = $code;
+ } else {
+ $this->colorFg = new BCGColor($code);
+ }
+ }
+
+ /**
+ * Gets the background color of the barcode.
+ *
+ * @return BCGColor
+ */
+ public function getBackgroundColor() {
+ return $this->colorBg;
+ }
+
+ /**
+ * 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
+ */
+ public function setBackgroundColor($code) {
+ if ($code instanceof BCGColor) {
+ $this->colorBg = $code;
+ } else {
+ $this->colorBg = new BCGColor($code);
+ }
+
+ foreach ($this->labels as $label) {
+ $label->setBackgroundColor($this->colorBg);
+ }
+ }
+
+ /**
+ * Sets the color.
+ *
+ * @param mixed $fg
+ * @param mixed $bg
+ */
+ public function setColor($fg, $bg) {
+ $this->setForegroundColor($fg);
+ $this->setBackgroundColor($bg);
+ }
+
+ /**
+ * Gets the scale of the barcode.
+ *
+ * @return int
+ */
+ public function getScale() {
+ return $this->scale;
+ }
+
+ /**
+ * Sets the scale of the barcode in pixel.
+ * If the scale is lower than 1, an exception is raised.
+ *
+ * @param int $scale
+ */
+ public function setScale($scale) {
+ $scale = intval($scale);
+ if ($scale <= 0) {
+ throw new BCGArgumentException('The scale must be larger than 0.', 'scale');
+ }
+
+ $this->scale = $scale;
+ }
+
+ /**
+ * Abstract method that draws the barcode on the resource.
+ *
+ * @param resource $im
+ */
+ public abstract function draw($im);
+
+ /**
+ * Returns the maximal size of a barcode.
+ * [0]->width
+ * [1]->height
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $labels = $this->getBiggestLabels(false);
+ $pixelsAround = array(0, 0, 0, 0); // TRBL
+ if (isset($labels[BCGLabel::POSITION_TOP])) {
+ $dimension = $labels[BCGLabel::POSITION_TOP]->getDimension();
+ $pixelsAround[0] += $dimension[1];
+ }
+
+ if (isset($labels[BCGLabel::POSITION_RIGHT])) {
+ $dimension = $labels[BCGLabel::POSITION_RIGHT]->getDimension();
+ $pixelsAround[1] += $dimension[0];
+ }
+
+ if (isset($labels[BCGLabel::POSITION_BOTTOM])) {
+ $dimension = $labels[BCGLabel::POSITION_BOTTOM]->getDimension();
+ $pixelsAround[2] += $dimension[1];
+ }
+
+ if (isset($labels[BCGLabel::POSITION_LEFT])) {
+ $dimension = $labels[BCGLabel::POSITION_LEFT]->getDimension();
+ $pixelsAround[3] += $dimension[0];
+ }
+
+ $finalW = ($w + $this->offsetX) * $this->scale;
+ $finalH = ($h + $this->offsetY) * $this->scale;
+
+ // This section will check if a top/bottom label is too big for its width and left/right too big for its height
+ $reversedLabels = $this->getBiggestLabels(true);
+ foreach ($reversedLabels as $label) {
+ $dimension = $label->getDimension();
+ $alignment = $label->getAlignment();
+ if ($label->getPosition() === BCGLabel::POSITION_LEFT || $label->getPosition() === BCGLabel::POSITION_RIGHT) {
+ if ($alignment === BCGLabel::ALIGN_TOP) {
+ $pixelsAround[2] = max($pixelsAround[2], $dimension[1] - $finalH);
+ } elseif ($alignment === BCGLabel::ALIGN_CENTER) {
+ $temp = ceil(($dimension[1] - $finalH) / 2);
+ $pixelsAround[0] = max($pixelsAround[0], $temp);
+ $pixelsAround[2] = max($pixelsAround[2], $temp);
+ } elseif ($alignment === BCGLabel::ALIGN_BOTTOM) {
+ $pixelsAround[0] = max($pixelsAround[0], $dimension[1] - $finalH);
+ }
+ } else {
+ if ($alignment === BCGLabel::ALIGN_LEFT) {
+ $pixelsAround[1] = max($pixelsAround[1], $dimension[0] - $finalW);
+ } elseif ($alignment === BCGLabel::ALIGN_CENTER) {
+ $temp = ceil(($dimension[0] - $finalW) / 2);
+ $pixelsAround[1] = max($pixelsAround[1], $temp);
+ $pixelsAround[3] = max($pixelsAround[3], $temp);
+ } elseif ($alignment === BCGLabel::ALIGN_RIGHT) {
+ $pixelsAround[3] = max($pixelsAround[3], $dimension[0] - $finalW);
+ }
+ }
+ }
+
+ $this->pushLabel[0] = $pixelsAround[3];
+ $this->pushLabel[1] = $pixelsAround[0];
+
+ $finalW = ($w + $this->offsetX) * $this->scale + $pixelsAround[1] + $pixelsAround[3];
+ $finalH = ($h + $this->offsetY) * $this->scale + $pixelsAround[0] + $pixelsAround[2];
+
+ return array($finalW, $finalH);
+ }
+
+ /**
+ * Gets the X offset.
+ *
+ * @return int
+ */
+ public function getOffsetX() {
+ return $this->offsetX;
+ }
+
+ /**
+ * Sets the X offset.
+ *
+ * @param int $offsetX
+ */
+ public function setOffsetX($offsetX) {
+ $offsetX = intval($offsetX);
+ if ($offsetX < 0) {
+ throw new BCGArgumentException('The offset X must be 0 or larger.', 'offsetX');
+ }
+
+ $this->offsetX = $offsetX;
+ }
+
+ /**
+ * Gets the Y offset.
+ *
+ * @return int
+ */
+ public function getOffsetY() {
+ return $this->offsetY;
+ }
+
+ /**
+ * Sets the Y offset.
+ *
+ * @param int $offsetY
+ */
+ public function setOffsetY($offsetY) {
+ $offsetY = intval($offsetY);
+ if ($offsetY < 0) {
+ throw new BCGArgumentException('The offset Y must be 0 or larger.', 'offsetY');
+ }
+
+ $this->offsetY = $offsetY;
+ }
+
+ /**
+ * Adds the label to the drawing.
+ *
+ * @param BCGLabel $label
+ */
+ public function addLabel(BCGLabel $label) {
+ $label->setBackgroundColor($this->colorBg);
+ $this->labels[] = $label;
+ }
+
+ /**
+ * Removes the label from the drawing.
+ *
+ * @param BCGLabel $label
+ */
+ public function removeLabel(BCGLabel $label) {
+ $remove = -1;
+ $c = count($this->labels);
+ for ($i = 0; $i < $c; $i++) {
+ if ($this->labels[$i] === $label) {
+ $remove = $i;
+ break;
+ }
+ }
+
+ if ($remove > -1) {
+ array_splice($this->labels, $remove, 1);
+ }
+ }
+
+ /**
+ * Clears the labels.
+ */
+ public function clearLabels() {
+ $this->labels = array();
+ }
+
+ /**
+ * Draws the text.
+ * The coordinate passed are the positions of the barcode.
+ * $x1 and $y1 represent the top left corner.
+ * $x2 and $y2 represent the bottom right corner.
+ *
+ * @param resource $im
+ * @param int $x1
+ * @param int $y1
+ * @param int $x2
+ * @param int $y2
+ */
+ protected function drawText($im, $x1, $y1, $x2, $y2) {
+ foreach ($this->labels as $label) {
+ $label->draw($im,
+ ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0],
+ ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1],
+ ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0],
+ ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1]);
+ }
+ }
+
+ /**
+ * Draws 1 pixel on the resource at a specific position with a determined color.
+ *
+ * @param resource $im
+ * @param int $x
+ * @param int $y
+ * @param int $color
+ */
+ protected function drawPixel($im, $x, $y, $color = self::COLOR_FG) {
+ $xR = ($x + $this->offsetX) * $this->scale + $this->pushLabel[0];
+ $yR = ($y + $this->offsetY) * $this->scale + $this->pushLabel[1];
+
+ // We always draw a rectangle
+ imagefilledrectangle($im,
+ $xR,
+ $yR,
+ $xR + $this->scale - 1,
+ $yR + $this->scale - 1,
+ $this->getColor($im, $color));
+ }
+
+ /**
+ * Draws an empty rectangle on the resource at a specific position with a determined color.
+ *
+ * @param resource $im
+ * @param int $x1
+ * @param int $y1
+ * @param int $x2
+ * @param int $y2
+ * @param int $color
+ */
+ protected function drawRectangle($im, $x1, $y1, $x2, $y2, $color = self::COLOR_FG) {
+ if ($this->scale === 1) {
+ imagefilledrectangle($im,
+ ($x1 + $this->offsetX) + $this->pushLabel[0],
+ ($y1 + $this->offsetY) + $this->pushLabel[1],
+ ($x2 + $this->offsetX) + $this->pushLabel[0],
+ ($y2 + $this->offsetY) + $this->pushLabel[1],
+ $this->getColor($im, $color));
+ } else {
+ imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0], ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1], ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, $this->getColor($im, $color));
+ imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0], ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1], ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, $this->getColor($im, $color));
+ imagefilledrectangle($im, ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0], ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1], ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, $this->getColor($im, $color));
+ imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0], ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1], ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, $this->getColor($im, $color));
+ }
+ }
+
+ /**
+ * Draws a filled rectangle on the resource at a specific position with a determined color.
+ *
+ * @param resource $im
+ * @param int $x1
+ * @param int $y1
+ * @param int $x2
+ * @param int $y2
+ * @param int $color
+ */
+ protected function drawFilledRectangle($im, $x1, $y1, $x2, $y2, $color = self::COLOR_FG) {
+ if ($x1 > $x2) { // Swap
+ $x1 ^= $x2 ^= $x1 ^= $x2;
+ }
+
+ if ($y1 > $y2) { // Swap
+ $y1 ^= $y2 ^= $y1 ^= $y2;
+ }
+
+ imagefilledrectangle($im,
+ ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0],
+ ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1],
+ ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1,
+ ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1,
+ $this->getColor($im, $color));
+ }
+
+ /**
+ * Allocates the color based on the integer.
+ *
+ * @param resource $im
+ * @param int $color
+ * @return resource
+ */
+ protected function getColor($im, $color) {
+ if ($color === self::COLOR_BG) {
+ return $this->colorBg->allocate($im);
+ } else {
+ return $this->colorFg->allocate($im);
+ }
+ }
+
+ /**
+ * Returning the biggest label widths for LEFT/RIGHT and heights for TOP/BOTTOM.
+ *
+ * @param bool $reversed
+ * @return BCGLabel[]
+ */
+ private function getBiggestLabels($reversed = false) {
+ $searchLR = $reversed ? 1 : 0;
+ $searchTB = $reversed ? 0 : 1;
+
+ $labels = array();
+ foreach ($this->labels as $label) {
+ $position = $label->getPosition();
+ if (isset($labels[$position])) {
+ $savedDimension = $labels[$position]->getDimension();
+ $dimension = $label->getDimension();
+ if ($position === BCGLabel::POSITION_LEFT || $position === BCGLabel::POSITION_RIGHT) {
+ if ($dimension[$searchLR] > $savedDimension[$searchLR]) {
+ $labels[$position] = $label;
+ }
+ } else {
+ if ($dimension[$searchTB] > $savedDimension[$searchTB]) {
+ $labels[$position] = $label;
+ }
+ }
+ } else {
+ $labels[$position] = $label;
+ }
+ }
+
+ return $labels;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGBarcode1D.php b/application/libraries/barcodegen/class/BCGBarcode1D.php
new file mode 100755
index 000000000..a4f5c50e3
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGBarcode1D.php
@@ -0,0 +1,259 @@
+setThickness(30);
+
+ $this->defaultLabel = new BCGLabel();
+ $this->defaultLabel->setPosition(BCGLabel::POSITION_BOTTOM);
+ $this->setLabel(self::AUTO_LABEL);
+ $this->setFont(new BCGFontPhp(5));
+
+ $this->text = '';
+ $this->checksumValue = false;
+ $this->positionX = 0;
+ }
+
+ /**
+ * Gets the thickness.
+ *
+ * @return int
+ */
+ public function getThickness() {
+ return $this->thickness;
+ }
+
+ /**
+ * Sets the thickness.
+ *
+ * @param int $thickness
+ */
+ public function setThickness($thickness) {
+ $thickness = intval($thickness);
+ if ($thickness <= 0) {
+ throw new BCGArgumentException('The thickness must be larger than 0.', 'thickness');
+ }
+
+ $this->thickness = $thickness;
+ }
+
+ /**
+ * Gets the label.
+ * If the label was set to BCGBarcode1D::AUTO_LABEL, the label will display the value from the text parsed.
+ *
+ * @return string
+ */
+ public function getLabel() {
+ $label = $this->label;
+ if ($this->label === self::AUTO_LABEL) {
+ $label = $this->text;
+ if ($this->displayChecksum === true && ($checksum = $this->processChecksum()) !== false) {
+ $label .= $checksum;
+ }
+ }
+
+ return $label;
+ }
+
+ /**
+ * Sets the label.
+ * You can use BCGBarcode::AUTO_LABEL to have the label automatically written based on the parsed text.
+ *
+ * @param string $label
+ */
+ public function setLabel($label) {
+ $this->label = $label;
+ }
+
+ /**
+ * Gets the font.
+ *
+ * @return BCGFont
+ */
+ public function getFont() {
+ return $this->font;
+ }
+
+ /**
+ * Sets the font.
+ *
+ * @param mixed $font BCGFont or int
+ */
+ public function setFont($font) {
+ if (is_int($font)) {
+ if ($font === 0) {
+ $font = null;
+ } else {
+ $font = new BCGFontPhp($font);
+ }
+ }
+
+ $this->font = $font;
+ }
+
+ /**
+ * Parses the text before displaying it.
+ *
+ * @param mixed $text
+ */
+ public function parse($text) {
+ $this->text = $text;
+ $this->checksumValue = false; // Reset checksumValue
+ $this->validate();
+
+ parent::parse($text);
+
+ $this->addDefaultLabel();
+ }
+
+ /**
+ * Gets the checksum of a Barcode.
+ * If no checksum is available, return FALSE.
+ *
+ * @return string
+ */
+ public function getChecksum() {
+ 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 $displayChecksum
+ */
+ public function setDisplayChecksum($displayChecksum) {
+ $this->displayChecksum = (bool)$displayChecksum;
+ }
+
+ /**
+ * Adds the default label.
+ */
+ protected function addDefaultLabel() {
+ $label = $this->getLabel();
+ $font = $this->font;
+ if ($label !== null && $label !== '' && $font !== null && $this->defaultLabel !== null) {
+ $this->defaultLabel->setText($label);
+ $this->defaultLabel->setFont($font);
+ $this->addLabel($this->defaultLabel);
+ }
+ }
+
+ /**
+ * Validates the input
+ */
+ protected function validate() {
+ // No validation in the abstract class.
+ }
+
+ /**
+ * Returns the index in $keys (useful for checksum).
+ *
+ * @param mixed $var
+ * @return mixed
+ */
+ protected function findIndex($var) {
+ return array_search($var, $this->keys);
+ }
+
+ /**
+ * Returns the code of the char (useful for drawing bars).
+ *
+ * @param mixed $var
+ * @return string
+ */
+ protected function findCode($var) {
+ return $this->code[$this->findIndex($var)];
+ }
+
+ /**
+ * Draws all chars thanks to $code. If $startBar is true, the line begins by a space.
+ * If $startBar is false, the line begins by a bar.
+ *
+ * @param resource $im
+ * @param string $code
+ * @param boolean $startBar
+ */
+ protected function drawChar($im, $code, $startBar = true) {
+ $colors = array(BCGBarcode::COLOR_FG, BCGBarcode::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 int $color
+ */
+ protected function drawSingleBar($im, $color) {
+ $this->drawFilledRectangle($im, $this->positionX, 0, $this->positionX, $this->thickness - 1, $color);
+ }
+
+ /**
+ * Moving the pointer right to write a bar.
+ */
+ protected function nextX() {
+ $this->positionX++;
+ }
+
+ /**
+ * Method that saves FALSE into the checksumValue. This means no checksum
+ * but this method should be overriden when needed.
+ */
+ protected function calculateChecksum() {
+ $this->checksumValue = false;
+ }
+
+ /**
+ * Returns FALSE because there is no checksum. This method should be
+ * overriden to return correctly the checksum in string with checksumValue.
+ *
+ * @return string
+ */
+ protected function processChecksum() {
+ return false;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGColor.php b/application/libraries/barcodegen/class/BCGColor.php
new file mode 100755
index 000000000..5ece68db7
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGColor.php
@@ -0,0 +1,154 @@
+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] = self::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;
+ }
+ }
+
+ /**
+ * Sets the color transparent.
+ *
+ * @param bool $transparent
+ */
+ public function setTransparent($transparent) {
+ $this->transparent = $transparent;
+ }
+
+ /**
+ * Returns Red Color.
+ *
+ * @return int
+ */
+ public function r() {
+ return $this->r;
+ }
+
+ /**
+ * Returns Green Color.
+ *
+ * @return int
+ */
+ public function g() {
+ return $this->g;
+ }
+
+ /**
+ * Returns Blue Color.
+ *
+ * @return int
+ */
+ public function b() {
+ return $this->b;
+ }
+
+ /**
+ * Returns the int value for PHP color.
+ *
+ * @param resource $im
+ * @return int
+ */
+ public function allocate(&$im) {
+ $allocated = imagecolorallocate($im, $this->r, $this->g, $this->b);
+ if ($this->transparent) {
+ return imagecolortransparent($im, $allocated);
+ } else {
+ return $allocated;
+ }
+ }
+
+ /**
+ * 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
+ */
+ public static function getColor($code, $default = 'white') {
+ 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 self::getColor($default, 'white');
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGDrawException.php b/application/libraries/barcodegen/class/BCGDrawException.php
new file mode 100755
index 000000000..8c85f8c2b
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGDrawException.php
@@ -0,0 +1,21 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGDrawing.php b/application/libraries/barcodegen/class/BCGDrawing.php
new file mode 100755
index 000000000..6766c1e41
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGDrawing.php
@@ -0,0 +1,248 @@
+im = null;
+ $this->setFilename($filename);
+ $this->color = $color;
+ $this->dpi = null;
+ $this->rotateDegree = 0.0;
+ }
+
+ /**
+ * Destructor.
+ */
+ public function __destruct() {
+ $this->destroy();
+ }
+
+ /**
+ * Gets the filename.
+ *
+ * @return string
+ */
+ public function getFilename() {
+ return $this->filename;
+ }
+
+ /**
+ * Sets the filename.
+ *
+ * @param string $filaneme
+ */
+ public function setFilename($filename) {
+ $this->filename = $filename;
+ }
+
+ /**
+ * @return resource.
+ */
+ public function get_im() {
+ return $this->im;
+ }
+
+ /**
+ * Sets the image.
+ *
+ * @param resource $im
+ */
+ public function set_im($im) {
+ $this->im = $im;
+ }
+
+ /**
+ * Gets barcode for drawing.
+ *
+ * @return BCGBarcode
+ */
+ public function getBarcode() {
+ return $this->barcode;
+ }
+
+ /**
+ * Sets barcode for drawing.
+ *
+ * @param BCGBarcode $barcode
+ */
+ public function setBarcode(BCGBarcode $barcode) {
+ $this->barcode = $barcode;
+ }
+
+ /**
+ * Gets the DPI for supported filetype.
+ *
+ * @return float
+ */
+ public function getDPI() {
+ return $this->dpi;
+ }
+
+ /**
+ * Sets the DPI for supported filetype.
+ *
+ * @param float $dpi
+ */
+ public function setDPI($dpi) {
+ $this->dpi = $dpi;
+ }
+
+ /**
+ * Gets the rotation angle in degree clockwise.
+ *
+ * @return float
+ */
+ public function getRotationAngle() {
+ return $this->rotateDegree;
+ }
+
+ /**
+ * Sets the rotation angle in degree clockwise.
+ *
+ * @param float $degree
+ */
+ public function setRotationAngle($degree) {
+ $this->rotateDegree = (float)$degree;
+ }
+
+ /**
+ * Draws the barcode on the image $im.
+ */
+ public function draw() {
+ $size = $this->barcode->getDimension(0, 0);
+ $this->w = max(1, $size[0]);
+ $this->h = max(1, $size[1]);
+ $this->init();
+ $this->barcode->draw($this->im);
+ }
+
+ /**
+ * Saves $im into the file (many format available).
+ *
+ * @param int $image_style
+ * @param int $quality
+ */
+ public function finish($image_style = self::IMG_FORMAT_PNG, $quality = 100) {
+ $drawer = null;
+
+ $im = $this->im;
+ if ($this->rotateDegree > 0.0) {
+ if (function_exists('imagerotate')) {
+ $im = imagerotate($this->im, 360 - $this->rotateDegree, $this->color->allocate($this->im));
+ } else {
+ throw new BCGDrawException('The method imagerotate doesn\'t exist on your server. Do not use any rotation.');
+ }
+ }
+
+ if ($image_style === self::IMG_FORMAT_PNG) {
+ $drawer = new BCGDrawPNG($im);
+ $drawer->setFilename($this->filename);
+ $drawer->setDPI($this->dpi);
+ } elseif ($image_style === self::IMG_FORMAT_JPEG) {
+ $drawer = new BCGDrawJPG($im);
+ $drawer->setFilename($this->filename);
+ $drawer->setDPI($this->dpi);
+ $drawer->setQuality($quality);
+ } elseif ($image_style === self::IMG_FORMAT_GIF) {
+ // Some PHP versions have a bug if passing 2nd argument as null.
+ if ($this->filename === null || $this->filename === '') {
+ imagegif($im);
+ } else {
+ imagegif($im, $this->filename);
+ }
+ } elseif ($image_style === self::IMG_FORMAT_WBMP) {
+ imagewbmp($im, $this->filename);
+ }
+
+ if ($drawer !== null) {
+ $drawer->draw();
+ }
+ }
+
+ /**
+ * Writes the Error on the picture.
+ *
+ * @param Exception $exception
+ */
+ public function drawException($exception) {
+ $this->w = 1;
+ $this->h = 1;
+ $this->init();
+
+ // Is the image big enough?
+ $w = imagesx($this->im);
+ $h = imagesy($this->im);
+
+ $text = 'Error: ' . $exception->getMessage();
+
+ $width = imagefontwidth(2) * strlen($text);
+ $height = imagefontheight(2);
+ 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($this->im, 0, 0));
+ imagecopy($newimg, $this->im, 0, 0, 0, 0, $w, $h);
+ $this->im = $newimg;
+ }
+
+ $black = new BCGColor('black');
+ imagestring($this->im, 2, 0, 0, $text, $black->allocate($this->im));
+ }
+
+ /**
+ * Free the memory of PHP (called also by destructor).
+ */
+ public function destroy() {
+ @imagedestroy($this->im);
+ }
+
+ /**
+ * Init Image and color background.
+ */
+ private 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));
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGFont.php b/application/libraries/barcodegen/class/BCGFont.php
new file mode 100755
index 000000000..a2a8f2f19
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGFont.php
@@ -0,0 +1,23 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGFontFile.php b/application/libraries/barcodegen/class/BCGFontFile.php
new file mode 100755
index 000000000..756046686
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGFontFile.php
@@ -0,0 +1,209 @@
+path = $fontPath;
+ $this->size = $size;
+ $this->foregroundColor = new BCGColor('black');
+ $this->setRotationAngle(0);
+ $this->setBoxFix(self::PHP_BOX_FIX);
+ }
+
+ /**
+ * Gets the text associated to the font.
+ *
+ * @return string
+ */
+ public function getText() {
+ return $this->text;
+ }
+
+ /**
+ * Sets the text associated to the font.
+ *
+ * @param string text
+ */
+ public function setText($text) {
+ $this->text = $text;
+ $this->box = null;
+ }
+
+ /**
+ * Gets the rotation in degree.
+ *
+ * @return int
+ */
+ public function getRotationAngle() {
+ return (360 - $this->rotationAngle) % 360;
+ }
+
+ /**
+ * Sets the rotation in degree.
+ *
+ * @param int
+ */
+ public function setRotationAngle($rotationAngle) {
+ $this->rotationAngle = (int)$rotationAngle;
+ if ($this->rotationAngle !== 90 && $this->rotationAngle !== 180 && $this->rotationAngle !== 270) {
+ $this->rotationAngle = 0;
+ }
+
+ $this->rotationAngle = (360 - $this->rotationAngle) % 360;
+
+ $this->box = null;
+ }
+
+ /**
+ * Gets the background color.
+ *
+ * @return BCGColor
+ */
+ public function getBackgroundColor() {
+ }
+
+ /**
+ * Sets the background color.
+ *
+ * @param BCGColor $backgroundColor
+ */
+ public function setBackgroundColor($backgroundColor) {
+ }
+
+ /**
+ * Gets the foreground color.
+ *
+ * @return BCGColor
+ */
+ public function getForegroundColor() {
+ return $this->foregroundColor;
+ }
+
+ /**
+ * Sets the foreground color.
+ *
+ * @param BCGColor $foregroundColor
+ */
+ public function setForegroundColor($foregroundColor) {
+ $this->foregroundColor = $foregroundColor;
+ }
+
+ /**
+ * Gets the box fix information.
+ *
+ * @return int
+ */
+ public function getBoxFix() {
+ return $this->boxFix;
+ }
+
+ /**
+ * Sets the box fix information.
+ *
+ * @param int $value
+ */
+ public function setBoxFix($value) {
+ $this->boxFix = intval($value);
+ }
+
+ /**
+ * Returns the width and height that the text takes to be written.
+ *
+ * @return int[]
+ */
+ public function getDimension() {
+ $w = 0.0;
+ $h = 0.0;
+ $box = $this->getBox();
+
+ if ($box !== null) {
+ $minX = min(array($box[0], $box[2], $box[4], $box[6]));
+ $maxX = max(array($box[0], $box[2], $box[4], $box[6]));
+ $minY = min(array($box[1], $box[3], $box[5], $box[7]));
+ $maxY = max(array($box[1], $box[3], $box[5], $box[7]));
+
+ $w = $maxX - $minX;
+ $h = $maxY - $minY;
+ }
+
+ $rotationAngle = $this->getRotationAngle();
+ if ($rotationAngle === 90 || $rotationAngle === 270) {
+ return array($h + self::PHP_BOX_FIX, $w);
+ } else {
+ return array($w + self::PHP_BOX_FIX, $h);
+ }
+ }
+
+ /**
+ * Draws the text on the image at a specific position.
+ * $x and $y represent the left bottom corner.
+ *
+ * @param resource $im
+ * @param int $x
+ * @param int $y
+ */
+ public function draw($im, $x, $y) {
+ $drawingPosition = $this->getDrawingPosition($x, $y);
+ imagettftext($im, $this->size, $this->rotationAngle, $drawingPosition[0], $drawingPosition[1], $this->foregroundColor->allocate($im), $this->path, $this->text);
+ }
+
+ private function getDrawingPosition($x, $y) {
+ $dimension = $this->getDimension();
+ $box = $this->getBox();
+ $rotationAngle = $this->getRotationAngle();
+ if ($rotationAngle === 0) {
+ $y += abs(min($box[5], $box[7]));
+ } elseif ($rotationAngle === 90) {
+ $x += abs(min($box[5], $box[7]));
+ $y += $dimension[1];
+ } elseif ($rotationAngle === 180) {
+ $x += $dimension[0];
+ $y += abs(max($box[1], $box[3]));
+ } elseif ($rotationAngle === 270) {
+ $x += abs(max($box[1], $box[3]));
+ }
+
+ return array($x, $y);
+ }
+
+ private function getBox() {
+ if ($this->box === null) {
+ $gd = imagecreate(1, 1);
+ $this->box = imagettftext($gd, $this->size, 0, 0, 0, 0, $this->path, $this->text);
+ }
+
+ return $this->box;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGFontPhp.php b/application/libraries/barcodegen/class/BCGFontPhp.php
new file mode 100755
index 000000000..e556e49aa
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGFontPhp.php
@@ -0,0 +1,153 @@
+font = max(0, intval($font));
+ $this->backgroundColor = new BCGColor('white');
+ $this->foregroundColor = new BCGColor('black');
+ $this->setRotationAngle(0);
+ }
+
+ /**
+ * Gets the text associated to the font.
+ *
+ * @return string
+ */
+ public function getText() {
+ return $this->text;
+ }
+
+ /**
+ * Sets the text associated to the font.
+ *
+ * @param string text
+ */
+ public function setText($text) {
+ $this->text = $text;
+ }
+
+ /**
+ * Gets the rotation in degree.
+ *
+ * @return int
+ */
+ public function getRotationAngle() {
+ return (360 - $this->rotationAngle) % 360;
+ }
+
+ /**
+ * Sets the rotation in degree.
+ *
+ * @param int
+ */
+ public function setRotationAngle($rotationAngle) {
+ $this->rotationAngle = (int)$rotationAngle;
+ if ($this->rotationAngle !== 90 && $this->rotationAngle !== 180 && $this->rotationAngle !== 270) {
+ $this->rotationAngle = 0;
+ }
+
+ $this->rotationAngle = (360 - $this->rotationAngle) % 360;
+ }
+
+ /**
+ * Gets the background color.
+ *
+ * @return BCGColor
+ */
+ public function getBackgroundColor() {
+ return $this->backgroundColor;
+ }
+
+ /**
+ * Sets the background color.
+ *
+ * @param BCGColor $backgroundColor
+ */
+ public function setBackgroundColor($backgroundColor) {
+ $this->backgroundColor = $backgroundColor;
+ }
+
+ /**
+ * Gets the foreground color.
+ *
+ * @return BCGColor
+ */
+ public function getForegroundColor() {
+ return $this->foregroundColor;
+ }
+
+ /**
+ * Sets the foreground color.
+ *
+ * @param BCGColor $foregroundColor
+ */
+ public function setForegroundColor($foregroundColor) {
+ $this->foregroundColor = $foregroundColor;
+ }
+
+ /**
+ * Returns the width and height that the text takes to be written.
+ *
+ * @return int[]
+ */
+ public function getDimension() {
+ $w = imagefontwidth($this->font) * strlen($this->text);
+ $h = imagefontheight($this->font);
+
+ $rotationAngle = $this->getRotationAngle();
+ if ($rotationAngle === 90 || $rotationAngle === 270) {
+ return array($h, $w);
+ } else {
+ return array($w, $h);
+ }
+ }
+
+ /**
+ * Draws the text on the image at a specific position.
+ * $x and $y represent the left bottom corner.
+ *
+ * @param resource $im
+ * @param int $x
+ * @param int $y
+ */
+ public function draw($im, $x, $y) {
+ if ($this->getRotationAngle() !== 0) {
+ if (!function_exists('imagerotate')) {
+ throw new BCGDrawException('The method imagerotate doesn\'t exist on your server. Do not use any rotation.');
+ }
+
+ $w = imagefontwidth($this->font) * strlen($this->text);
+ $h = imagefontheight($this->font);
+ $gd = imagecreatetruecolor($w, $h);
+ imagefilledrectangle($gd, 0, 0, $w - 1, $h - 1, $this->backgroundColor->allocate($gd));
+ imagestring($gd, $this->font, 0, 0, $this->text, $this->foregroundColor->allocate($gd));
+ $gd = imagerotate($gd, $this->rotationAngle, 0);
+ imagecopy($im, $gd, $x, $y, 0, 0, imagesx($gd), imagesy($gd));
+ } else {
+ imagestring($im, $this->font, $x, $y, $this->text, $this->foregroundColor->allocate($im));
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGLabel.php b/application/libraries/barcodegen/class/BCGLabel.php
new file mode 100755
index 000000000..1a378001e
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGLabel.php
@@ -0,0 +1,320 @@
+setFont($font);
+ $this->setText($text);
+ $this->setPosition($position);
+ $this->setAlignment($alignment);
+ $this->setSpacing(4);
+ $this->setOffset(0);
+ $this->setRotationAngle(0);
+ $this->setBackgroundColor(new BCGColor('white'));
+ $this->setForegroundColor(new BCGColor('black'));
+ }
+
+ /**
+ * Gets the text.
+ *
+ * @return string
+ */
+ public function getText() {
+ return $this->font->getText();
+ }
+
+ /**
+ * Sets the text.
+ *
+ * @param string $text
+ */
+ public function setText($text) {
+ $this->text = $text;
+ $this->font->setText($this->text);
+ }
+
+ /**
+ * Gets the font.
+ *
+ * @return BCGFont
+ */
+ public function getFont() {
+ return $this->font;
+ }
+
+ /**
+ * Sets the font.
+ *
+ * @param BCGFont $font
+ */
+ public function setFont($font) {
+ if ($font === null) {
+ throw new BCGArgumentException('Font cannot be null.', 'font');
+ }
+
+ $this->font = clone $font;
+ $this->font->setText($this->text);
+ $this->font->setRotationAngle($this->rotationAngle);
+ $this->font->setBackgroundColor($this->backgroundColor);
+ $this->font->setForegroundColor($this->foregroundColor);
+ }
+
+ /**
+ * Gets the text position for drawing.
+ *
+ * @return int
+ */
+ public function getPosition() {
+ return $this->position;
+ }
+
+ /**
+ * Sets the text position for drawing.
+ *
+ * @param int $position
+ */
+ public function setPosition($position) {
+ $position = intval($position);
+ if ($position !== self::POSITION_TOP && $position !== self::POSITION_RIGHT && $position !== self::POSITION_BOTTOM && $position !== self::POSITION_LEFT) {
+ throw new BCGArgumentException('The text position must be one of a valid constant.', 'position');
+ }
+
+ $this->position = $position;
+ }
+
+ /**
+ * Gets the text alignment for drawing.
+ *
+ * @return int
+ */
+ public function getAlignment() {
+ return $this->alignment;
+ }
+
+ /**
+ * Sets the text alignment for drawing.
+ *
+ * @param int $alignment
+ */
+ public function setAlignment($alignment) {
+ $alignment = intval($alignment);
+ if ($alignment !== self::ALIGN_LEFT && $alignment !== self::ALIGN_TOP && $alignment !== self::ALIGN_CENTER && $alignment !== self::ALIGN_RIGHT && $alignment !== self::ALIGN_BOTTOM) {
+ throw new BCGArgumentException('The text alignment must be one of a valid constant.', 'alignment');
+ }
+
+ $this->alignment = $alignment;
+ }
+
+ /**
+ * Gets the offset.
+ *
+ * @return int
+ */
+ public function getOffset() {
+ return $this->offset;
+ }
+
+ /**
+ * Sets the offset.
+ *
+ * @param int $offset
+ */
+ public function setOffset($offset) {
+ $this->offset = intval($offset);
+ }
+
+ /**
+ * Gets the spacing.
+ *
+ * @return int
+ */
+ public function getSpacing() {
+ return $this->spacing;
+ }
+
+ /**
+ * Sets the spacing.
+ *
+ * @param int $spacing
+ */
+ public function setSpacing($spacing) {
+ $this->spacing = max(0, intval($spacing));
+ }
+
+ /**
+ * Gets the rotation angle in degree.
+ *
+ * @return int
+ */
+ public function getRotationAngle() {
+ return $this->font->getRotationAngle();
+ }
+
+ /**
+ * Sets the rotation angle in degree.
+ *
+ * @param int $rotationAngle
+ */
+ public function setRotationAngle($rotationAngle) {
+ $this->rotationAngle = intval($rotationAngle);
+ $this->font->setRotationAngle($this->rotationAngle);
+ }
+
+ /**
+ * Gets the background color in case of rotation.
+ *
+ * @return BCGColor
+ */
+ public function getBackgroundColor() {
+ return $this->backgroundColor;
+ }
+
+ /**
+ * Sets the background color in case of rotation.
+ *
+ * @param BCGColor $backgroundColor
+ */
+ public /*internal*/ function setBackgroundColor($backgroundColor) {
+ $this->backgroundColor = $backgroundColor;
+ $this->font->setBackgroundColor($this->backgroundColor);
+ }
+
+ /**
+ * Gets the foreground color.
+ *
+ * @return BCGColor
+ */
+ public function getForegroundColor() {
+ return $this->font->getForegroundColor();
+ }
+
+ /**
+ * Sets the foreground color.
+ *
+ * @param BCGColor $foregroundColor
+ */
+ public function setForegroundColor($foregroundColor) {
+ $this->foregroundColor = $foregroundColor;
+ $this->font->setForegroundColor($this->foregroundColor);
+ }
+
+ /**
+ * Gets the dimension taken by the label, including the spacing and offset.
+ * [0]: width
+ * [1]: height
+ *
+ * @return int[]
+ */
+ public function getDimension() {
+ $w = 0;
+ $h = 0;
+
+ $dimension = $this->font->getDimension();
+ $w = $dimension[0];
+ $h = $dimension[1];
+
+ if ($this->position === self::POSITION_TOP || $this->position === self::POSITION_BOTTOM) {
+ $h += $this->spacing;
+ $w += max(0, $this->offset);
+ } else {
+ $w += $this->spacing;
+ $h += max(0, $this->offset);
+ }
+
+ return array($w, $h);
+ }
+
+ /**
+ * Draws the text.
+ * The coordinate passed are the positions of the barcode.
+ * $x1 and $y1 represent the top left corner.
+ * $x2 and $y2 represent the bottom right corner.
+ *
+ * @param resource $im
+ * @param int $x1
+ * @param int $y1
+ * @param int $x2
+ * @param int $y2
+ */
+ public /*internal*/ function draw($im, $x1, $y1, $x2, $y2) {
+ $x = 0;
+ $y = 0;
+
+ $fontDimension = $this->font->getDimension();
+
+ if ($this->position === self::POSITION_TOP || $this->position === self::POSITION_BOTTOM) {
+ if ($this->position === self::POSITION_TOP) {
+ $y = $y1 - $this->spacing - $fontDimension[1];
+ } elseif ($this->position === self::POSITION_BOTTOM) {
+ $y = $y2 + $this->spacing;
+ }
+
+ if ($this->alignment === self::ALIGN_CENTER) {
+ $x = ($x2 - $x1) / 2 + $x1 - $fontDimension[0] / 2 + $this->offset;
+ } elseif ($this->alignment === self::ALIGN_LEFT) {
+ $x = $x1 + $this->offset;
+ } else {
+ $x = $x2 + $this->offset - $fontDimension[0];
+ }
+ } else {
+ if ($this->position === self::POSITION_LEFT) {
+ $x = $x1 - $this->spacing - $fontDimension[0];
+ } elseif ($this->position === self::POSITION_RIGHT) {
+ $x = $x2 + $this->spacing;
+ }
+
+ if ($this->alignment === self::ALIGN_CENTER) {
+ $y = ($y2 - $y1) / 2 + $y1 - $fontDimension[1] / 2 + $this->offset;
+ } elseif ($this->alignment === self::ALIGN_TOP) {
+ $y = $y1 + $this->offset;
+ } else {
+ $y = $y2 + $this->offset - $fontDimension[1];
+ }
+ }
+
+ $this->font->setText($this->text);
+ $this->font->draw($im, $x, $y);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGParseException.php b/application/libraries/barcodegen/class/BCGParseException.php
new file mode 100755
index 000000000..0582d0bca
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGParseException.php
@@ -0,0 +1,25 @@
+barcode = $barcode;
+ parent::__construct($message, 10000);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGcodabar.barcode.php b/application/libraries/barcodegen/class/BCGcodabar.barcode.php
new file mode 100755
index 000000000..9616fb905
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGcodabar.barcode.php
@@ -0,0 +1,122 @@
+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 */
+ );
+ }
+
+ /**
+ * Parses the text before displaying it.
+ *
+ * @param mixed $text
+ */
+ public function parse($text) {
+ parent::parse(strtoupper($text)); // Only Capital Letters are Allowed
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ $c = strlen($this->text);
+ for ($i = 0; $i < $c; $i++) {
+ $this->drawChar($im, $this->findCode($this->text[$i]), true);
+ }
+
+ $this->drawText($im, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $textLength = 0;
+ $c = strlen($this->text);
+ for ($i = 0; $i < $c; $i++) {
+ $index = $this->findIndex($this->text[$i]);
+ if ($index !== false) {
+ $textLength += 8;
+ $textLength += substr_count($this->code[$index], '1');
+ }
+ }
+
+ $w += $textLength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('codabar', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('codabar', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ // Must start by A, B, C or D
+ if ($c == 0 || ($this->text[0] !== 'A' && $this->text[0] !== 'B' && $this->text[0] !== 'C' && $this->text[0] !== 'D')) {
+ throw new BCGParseException('codabar', 'The text must start by the character A, B, C, or D.');
+ }
+
+ // Must end 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')) {
+ throw new BCGParseException('codabar', 'The text must end by the character A, B, C, or D.');
+ }
+
+ parent::validate();
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGcode11.barcode.php b/application/libraries/barcodegen/class/BCGcode11.barcode.php
new file mode 100755
index 000000000..2a21e9b32
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGcode11.barcode.php
@@ -0,0 +1,185 @@
+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
+ */
+ public function draw($im) {
+ // Starting Code
+ $this->drawChar($im, '001100', true);
+
+ // Chars
+ $c = strlen($this->text);
+ 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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $startlength = 8;
+
+ $textlength = 0;
+ $c = strlen($this->text);
+ for ($i = 0; $i < $c; $i++) {
+ $textlength += $this->getIndexLength($this->findIndex($this->text[$i]));
+ }
+
+ $checksumlength = 0;
+ $this->calculateChecksum();
+ $c = count($this->checksumValue);
+ for ($i = 0; $i < $c; $i++) {
+ $checksumlength += $this->getIndexLength($this->checksumValue[$i]);
+ }
+
+ $endlength = 7;
+
+ $w += $startlength + $textlength + $checksumlength + $endlength;
+ $h += $this->thickness;
+
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('code11', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('code11', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected 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;
+ }
+
+ private function getIndexLength($index) {
+ $length = 0;
+ if ($index !== false) {
+ $length += 6;
+ $length += substr_count($this->code[$index], '1');
+ }
+
+ return $length;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGcode128.barcode.php b/application/libraries/barcodegen/class/BCGcode128.barcode.php
new file mode 100755
index 000000000..da89080c4
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGcode128.barcode.php
@@ -0,0 +1,885 @@
+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->setStart($start);
+ $this->setTilde(true);
+
+ // Latches and Shifts
+ $this->latch = array(
+ array(null, self::KEYA_CODEB, self::KEYA_CODEC),
+ array(self::KEYB_CODEA, null, self::KEYB_CODEC),
+ array(self::KEYC_CODEA, self::KEYC_CODEB, null)
+ );
+ $this->shift = array(
+ array(null, self::KEYA_SHIFT),
+ array(self::KEYB_SHIFT, null)
+ );
+ $this->fnc = array(
+ array(self::KEYA_FNC1, self::KEYA_FNC2, self::KEYA_FNC3, self::KEYA_FNC4),
+ array(self::KEYB_FNC1, self::KEYB_FNC2, self::KEYB_FNC3, self::KEYB_FNC4),
+ array(self::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
+ */
+ public function setStart($table) {
+ if ($table !== 'A' && $table !== 'B' && $table !== 'C' && $table !== null) {
+ throw new BCGArgumentException('The starting table must be A, B, C or null.', 'table');
+ }
+
+ $this->starting_text = $table;
+ }
+
+ /**
+ * Gets the tilde.
+ *
+ * @return bool
+ */
+ public function getTilde() {
+ return $this->tilde;
+ }
+
+ /**
+ * 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
+ */
+ public function setTilde($accept) {
+ $this->tilde = (bool)$accept;
+ }
+
+ /**
+ * Parses the text before displaying it.
+ *
+ * @param mixed $text
+ */
+ public function parse($text) {
+ $this->setStartFromText($text);
+
+ $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 exception 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 ($seq !== '') {
+ $bitstream = $this->createBinaryStream($this->text, $seq);
+ $this->setData($bitstream);
+ }
+
+ $this->addDefaultLabel();
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ $c = count($this->data);
+ for ($i = 0; $i < $c; $i++) {
+ $this->drawChar($im, $this->data[$i], true);
+ }
+
+ $this->drawChar($im, '1', true);
+ $this->drawText($im, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ // Contains start + text + checksum + stop
+ $textlength = count($this->data) * 11;
+ $endlength = 2; // + final bar
+
+ $w += $textlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = count($this->data);
+ if ($c === 0) {
+ throw new BCGParseException('code128', 'No data has been entered.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected function processChecksum() {
+ if ($this->checksumValue === false) { // Calculate the checksum only once
+ $this->calculateChecksum();
+ }
+
+ if ($this->checksumValue !== false) {
+ if ($this->lastTable === 'C') {
+ return (string)$this->checksumValue;
+ }
+
+ return $this->{'keys' . $this->lastTable}[$this->checksumValue];
+ }
+
+ return false;
+ }
+
+ /**
+ * Specifies the starting_text table if none has been specified earlier.
+ *
+ * @param string $text
+ */
+ private 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, '/');
+ $length = strlen($text);
+ if ($length >= 4 && preg_match('/[' . $tmp . ']/', substr($text, 0, 4))) {
+ $this->starting_text = 'C';
+ } else {
+ if ($length > 0 && strpos($this->keysB, $text[0]) !== false) {
+ $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
+ */
+ private static 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 {
+ throw new BCGParseException('code128', 'Bad ~F. You must provide a number from 1 to 4.');
+ }
+ } else {
+ throw new BCGParseException('code128', 'Bad ~F. You must provide a number from 1 to 4.');
+ }
+ } else {
+ throw new BCGParseException('code128', 'Wrong code after the ~.');
+ }
+ } else {
+ throw new BCGParseException('code128', 'Wrong code after the ~.');
+ }
+ } else {
+ throw new BCGParseException('code128', 'There is no ~ at this location.');
+ }
+ }
+
+ /**
+ * 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
+ */
+ private function getSequenceParsed($text, $currentMode) {
+ if ($this->tilde) {
+ $sequence = '';
+ $previousPos = 0;
+ while (($pos = strpos($text, '~', $previousPos)) !== false) {
+ $tildeData = self::extractTilde($text, $pos);
+
+ $simpleTilde = ($tildeData === '~~');
+ if ($simpleTilde && $currentMode !== 'B') {
+ throw new BCGParseException('code128', 'The Table ' . $currentMode . ' doesn\'t contain the character ~.');
+ }
+
+ // At this point, we know we have ~Fx
+ if ($tildeData !== '~F1' && $currentMode === 'C') {
+ // The mode C doesn't support ~F2, ~F3, ~F4
+ throw new BCGParseException('code128', 'The Table C doesn\'t contain the function ' . $tildeData . '.');
+ }
+
+ $length = $pos - $previousPos;
+ if ($currentMode === 'C') {
+ if ($length % 2 === 1) {
+ throw new BCGParseException('code128', 'The text "' . $text . '" must have an even number of character to be encoded in Table C.');
+ }
+ }
+
+ $sequence .= str_repeat('.', $length);
+ $sequence .= '.';
+ $sequence .= (!$simpleTilde) ? 'F' : '';
+ $previousPos = $pos + strlen($tildeData);
+ }
+
+ // Flushing
+ $length = strlen($text) - $previousPos;
+ if ($currentMode === 'C') {
+ if ($length % 2 === 1) {
+ throw new BCGParseException('code128', 'The text "' . $text . '" must have an even number of character to be encoded in Table C.');
+ }
+ }
+
+ $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
+ */
+ private 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
+ throw new BCGParseException('code128', 'The text "' . $text . '" can\'t be parsed with the Table A. The character "' . $match[0] . '" is not allowed.');
+ } 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
+ */
+ private function setParseB($text, &$currentMode) {
+ $tmp = preg_quote($this->keysB, '/');
+
+ $match = array();
+ if (preg_match('/[^' . $tmp . ']/', $text, $match) === 1) {
+ // We found something not allowed
+ throw new BCGParseException('code128', 'The text "' . $text . '" can\'t be parsed with the Table B. The character "' . $match[0] . '" is not allowed.');
+ } 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
+ */
+ private 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
+ throw new BCGParseException('code128', 'The text "' . $text . '" can\'t be parsed with the Table C. The character "' . $match[0] . '" is not allowed.');
+ } 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
+ */
+ private 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 = self::extractTilde($text, $x);
+
+ if ($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;
+ }
+
+ // Do we have the next char a number?? OR a ~F1
+ $pos = strpos($this->keysC, $input);
+ 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
+ throw new BCGParseException('code128', 'Character ' . $input . ' not supported.');
+ }
+
+ 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 is 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 '';
+ }
+
+ 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[][]
+ */
+ private 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[] = self::KEY_STARTA;
+ $this->lastTable = 'A';
+ } elseif ($this->starting_text === 'B') {
+ $currentEncoding = 1;
+ $indcheck[] = self::KEY_STARTB;
+ $this->lastTable = 'B';
+ } elseif ($this->starting_text === 'C') {
+ $currentEncoding = 2;
+ $indcheck[] = self::KEY_STARTC;
+ $this->lastTable = 'C';
+ }
+
+ $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;
+ $this->lastTable = chr(65 + $inputI);
+ $data[] = $this->code[$latch];
+ $currentEncoding = $inputI;
+ }
+ }
+ }
+
+ return array($indcheck, $data);
+ }
+
+ /**
+ * Encodes characters, base on its encoding and sequence
+ *
+ * @param int[] $data
+ * @param int $encoding
+ * @param string $seq
+ * @param string $text
+ * @param int $i
+ * @param int $counter
+ * @param int[] $indcheck
+ */
+ private 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
+ */
+ private function setData($data) {
+ $this->indcheck = $data[0];
+ $this->data = $data[1];
+ $this->calculateChecksum();
+ $this->data[] = $this->code[$this->checksumValue];
+ $this->data[] = $this->code[self::KEY_STOP];
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGcode39.barcode.php b/application/libraries/barcodegen/class/BCGcode39.barcode.php
new file mode 100755
index 000000000..6a77c260a
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGcode39.barcode.php
@@ -0,0 +1,193 @@
+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);
+ }
+
+ /**
+ * Sets if we display the checksum.
+ *
+ * @param bool $checksum
+ */
+ public function setChecksum($checksum) {
+ $this->checksum = (bool)$checksum;
+ }
+
+ /**
+ * Parses the text before displaying it.
+ *
+ * @param mixed $text
+ */
+ public function parse($text) {
+ parent::parse(strtoupper($text)); // Only Capital Letters are Allowed
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ // Starting *
+ $this->drawChar($im, $this->code[$this->starting], true);
+
+ // Chars
+ $c = strlen($this->text);
+ 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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $textlength = 13 * strlen($this->text);
+ $startlength = 13;
+ $checksumlength = 0;
+ if ($this->checksum === true) {
+ $checksumlength = 13;
+ }
+
+ $endlength = 13;
+
+ $w += $startlength + $textlength + $checksumlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('code39', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('code39', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ if (strpos($this->text, '*') !== false) {
+ throw new BCGParseException('code39', 'The character \'*\' is not allowed.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected function processChecksum() {
+ if ($this->checksumValue === false) { // Calculate the checksum only once
+ $this->calculateChecksum();
+ }
+
+ if ($this->checksumValue !== false) {
+ return $this->keys[$this->checksumValue];
+ }
+
+ return false;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGcode39extended.barcode.php b/application/libraries/barcodegen/class/BCGcode39extended.barcode.php
new file mode 100755
index 000000000..67d991588
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGcode39extended.barcode.php
@@ -0,0 +1,208 @@
+keys[self::EXTENDED_1] = '($)';
+ $this->keys[self::EXTENDED_2] = '(/)';
+ $this->keys[self::EXTENDED_3] = '(+)';
+ $this->keys[self::EXTENDED_4] = '(%)';
+ }
+
+ /**
+ * Parses the text before displaying it.
+ *
+ * @param mixed $text
+ */
+ public function parse($text) {
+ $this->text = $text;
+
+ $data = array();
+ $indcheck = array();
+
+ $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 = self::getExtendedVersion($this->text[$i]);
+ if ($extended === false) {
+ throw new BCGParseException('code39extended', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ } else {
+ $extc = strlen($extended);
+ for ($j = 0; $j < $extc; $j++) {
+ $v = $extended[$j];
+ if ($v === '$') {
+ $indcheck[] = self::EXTENDED_1;
+ $data[] = $this->code[self::EXTENDED_1];
+ } elseif ($v === '%') {
+ $indcheck[] = self::EXTENDED_2;
+ $data[] = $this->code[self::EXTENDED_2];
+ } elseif ($v === '/') {
+ $indcheck[] = self::EXTENDED_3;
+ $data[] = $this->code[self::EXTENDED_3];
+ } elseif ($v === '+') {
+ $indcheck[] = self::EXTENDED_4;
+ $data[] = $this->code[self::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));
+ $this->addDefaultLabel();
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ // Starting *
+ $this->drawChar($im, $this->code[$this->starting], true);
+ $c = count($this->data);
+ 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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $textlength = 13 * count($this->data);
+ $startlength = 13;
+ $checksumlength = 0;
+ if ($this->checksum === true) {
+ $checksumlength = 13;
+ }
+
+ $endlength = 13;
+
+ $w += $startlength + $textlength + $checksumlength + $endlength;
+ $h += $this->thickness;
+ return BCGBarcode1D::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = count($this->data);
+ if ($c === 0) {
+ throw new BCGParseException('code39extended', 'No data has been entered.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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
+ */
+ private function setData($data) {
+ $this->indcheck = $data[0];
+ $this->data = $data[1];
+ $this->calculateChecksum();
+ }
+
+ /**
+ * Returns the extended reprensentation of the character.
+ *
+ * @param string $char
+ * @return string
+ */
+ private static 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;
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGcode93.barcode.php b/application/libraries/barcodegen/class/BCGcode93.barcode.php
new file mode 100755
index 000000000..7d9397c4b
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGcode93.barcode.php
@@ -0,0 +1,301 @@
+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' /*(*)*/
+ );
+ }
+
+ /**
+ * Parses the text before displaying it.
+ *
+ * @param mixed $text
+ */
+ public function parse($text) {
+ $this->text = $text;
+
+ $data = array();
+ $indcheck = array();
+
+ $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 = self::getExtendedVersion($this->text[$i]);
+ if ($extended === false) {
+ throw new BCGParseException('code93', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ } else {
+ $extc = strlen($extended);
+ for ($j = 0; $j < $extc; $j++) {
+ $v = $extended[$j];
+ if ($v === '$') {
+ $indcheck[] = self::EXTENDED_1;
+ $data[] = $this->code[self::EXTENDED_1];
+ } elseif ($v === '%') {
+ $indcheck[] = self::EXTENDED_2;
+ $data[] = $this->code[self::EXTENDED_2];
+ } elseif ($v === '/') {
+ $indcheck[] = self::EXTENDED_3;
+ $data[] = $this->code[self::EXTENDED_3];
+ } elseif ($v === '+') {
+ $indcheck[] = self::EXTENDED_4;
+ $data[] = $this->code[self::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));
+ $this->addDefaultLabel();
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ // Starting *
+ $this->drawChar($im, $this->code[$this->starting], true);
+ $c = count($this->data);
+ 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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $startlength = 9;
+ $textlength = 9 * count($this->data);
+ $checksumlength = 2 * 9;
+ $endlength = 9 + 1; // + final bar
+
+ $w += $startlength + $textlength + $checksumlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = count($this->data);
+ if ($c === 0) {
+ throw new BCGParseException('code93', 'No data has been entered.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected 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
+ */
+ private function setData($data) {
+ $this->indcheck = $data[0];
+ $this->data = $data[1];
+ $this->calculateChecksum();
+ }
+
+ /**
+ * Returns the extended reprensentation of the character.
+ *
+ * @param string $char
+ * @return string
+ */
+ private static 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;
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGean13.barcode.php b/application/libraries/barcodegen/class/BCGean13.barcode.php
new file mode 100755
index 000000000..3cf6d7175
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGean13.barcode.php
@@ -0,0 +1,322 @@
+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 */
+ );
+
+ $this->alignDefaultLabel(true);
+ }
+
+ public function alignDefaultLabel($align) {
+ $this->alignLabel = (bool)$align;
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ $this->drawBars($im);
+ $this->drawText($im, 0, 0, $this->positionX, $this->thickness);
+
+ if ($this->isDefaultEanLabelEnabled()) {
+ $dimension = $this->labelCenter1->getDimension();
+ $this->drawExtendedBars($im, $dimension[1] - 2);
+ }
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $startlength = 3;
+ $centerlength = 5;
+ $textlength = 12 * 7;
+ $endlength = 3;
+
+ $w += $startlength + $centerlength + $textlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Adds the default label.
+ */
+ protected function addDefaultLabel() {
+ if ($this->isDefaultEanLabelEnabled()) {
+ $this->processChecksum();
+ $label = $this->getLabel();
+ $font = $this->font;
+
+ $this->labelLeft = new BCGLabel(substr($label, 0, 1), $font, BCGLabel::POSITION_LEFT, BCGLabel::ALIGN_BOTTOM);
+ $this->labelLeft->setSpacing(4 * $this->scale);
+
+ $this->labelCenter1 = new BCGLabel(substr($label, 1, 6), $font, BCGLabel::POSITION_BOTTOM, BCGLabel::ALIGN_LEFT);
+ $labelCenter1Dimension = $this->labelCenter1->getDimension();
+ $this->labelCenter1->setOffset(($this->scale * 44 - $labelCenter1Dimension[0]) / 2 + $this->scale * 2);
+
+ $this->labelCenter2 = new BCGLabel(substr($label, 7, 5) . $this->keys[$this->checksumValue], $font, BCGLabel::POSITION_BOTTOM, BCGLabel::ALIGN_LEFT);
+ $this->labelCenter2->setOffset(($this->scale * 44 - $labelCenter1Dimension[0]) / 2 + $this->scale * 48);
+
+ if ($this->alignLabel) {
+ $labelDimension = $this->labelCenter1->getDimension();
+ $this->labelLeft->setOffset($labelDimension[1]);
+ } else {
+ $labelDimension = $this->labelLeft->getDimension();
+ $this->labelLeft->setOffset($labelDimension[1] / 2);
+ }
+
+ $this->addLabel($this->labelLeft);
+ $this->addLabel($this->labelCenter1);
+ $this->addLabel($this->labelCenter2);
+ }
+ }
+
+ /**
+ * Checks if the default ean label is enabled.
+ *
+ * @return bool
+ */
+ protected function isDefaultEanLabelEnabled() {
+ $label = $this->getLabel();
+ $font = $this->font;
+ return $label !== null && $label !== '' && $font !== null && $this->defaultLabel !== null;
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('ean13', 'No data has been entered.');
+ }
+
+ $this->checkCharsAllowed();
+ $this->checkCorrectLength();
+
+ parent::validate();
+ }
+
+ /**
+ * Check chars allowed.
+ */
+ protected function checkCharsAllowed() {
+ // 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) {
+ throw new BCGParseException('ean13', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+ }
+
+ /**
+ * Check correct length.
+ */
+ protected function checkCorrectLength() {
+ // If we have 13 chars, just flush the last one without throwing anything
+ $c = strlen($this->text);
+ if ($c === 13) {
+ $this->text = substr($this->text, 0, 12);
+ } elseif ($c !== 12) {
+ throw new BCGParseException('ean13', 'Must contain 12 digits, the 13th digit is automatically added.');
+ }
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected function processChecksum() {
+ if ($this->checksumValue === false) { // Calculate the checksum only once
+ $this->calculateChecksum();
+ }
+
+ if ($this->checksumValue !== false) {
+ return $this->keys[$this->checksumValue];
+ }
+
+ return false;
+ }
+
+ /**
+ * Draws the bars
+ *
+ * @param resource $im
+ */
+ protected 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, self::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);
+ }
+
+ /**
+ * Draws the extended bars on the image.
+ *
+ * @param resource $im
+ * @param int $plus
+ */
+ protected function drawExtendedBars($im, $plus) {
+ $rememberX = $this->positionX;
+ $rememberH = $this->thickness;
+
+ // We increase the bars
+ $this->thickness = $this->thickness + intval($plus / $this->scale);
+ $this->positionX = 0;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ // Center Guard Bar
+ $this->positionX += 44;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ // Last Bars
+ $this->positionX += 44;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ $this->positionX = $rememberX;
+ $this->thickness = $rememberH;
+ }
+
+ /**
+ * Inverses the string when the $inverse parameter is equal to 1.
+ *
+ * @param string $text
+ * @param int $inverse
+ * @return string
+ */
+ private static function inverse($text, $inverse = 1) {
+ if ($inverse === 1) {
+ $text = strrev($text);
+ }
+
+ return $text;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGean8.barcode.php b/application/libraries/barcodegen/class/BCGean8.barcode.php
new file mode 100755
index 000000000..818a2fd94
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGean8.barcode.php
@@ -0,0 +1,244 @@
+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
+ */
+ public function draw($im) {
+ // 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, 0, 0, $this->positionX, $this->thickness);
+
+ if ($this->isDefaultEanLabelEnabled()) {
+ $dimension = $this->labelRight->getDimension();
+ $this->drawExtendedBars($im, $dimension[1] - 2);
+ }
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $startlength = 3;
+ $centerlength = 5;
+ $textlength = 8 * 7;
+ $endlength = 3;
+
+ $w += $startlength + $centerlength + $textlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Adds the default label.
+ */
+ protected function addDefaultLabel() {
+ if ($this->isDefaultEanLabelEnabled()) {
+ $this->processChecksum();
+ $label = $this->getLabel();
+ $font = $this->font;
+
+ $this->labelLeft = new BCGLabel(substr($label, 0, 4), $font, BCGLabel::POSITION_BOTTOM, BCGLabel::ALIGN_LEFT);
+ $labelLeftDimension = $this->labelLeft->getDimension();
+ $this->labelLeft->setOffset(($this->scale * 30 - $labelLeftDimension[0]) / 2 + $this->scale * 2);
+
+ $this->labelRight = new BCGLabel(substr($label, 4, 3) . $this->keys[$this->checksumValue], $font, BCGLabel::POSITION_BOTTOM, BCGLabel::ALIGN_LEFT);
+ $labelRightDimension = $this->labelRight->getDimension();
+ $this->labelRight->setOffset(($this->scale * 30 - $labelRightDimension[0]) / 2 + $this->scale * 34);
+
+ $this->addLabel($this->labelLeft);
+ $this->addLabel($this->labelRight);
+ }
+ }
+
+ /**
+ * Checks if the default ean label is enabled.
+ *
+ * @return bool
+ */
+ protected function isDefaultEanLabelEnabled() {
+ $label = $this->getLabel();
+ $font = $this->font;
+ return $label !== null && $label !== '' && $font !== null && $this->defaultLabel !== null;
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('ean8', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('ean8', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ // If we have 8 chars just flush the last one
+ if ($c === 8) {
+ $this->text = substr($this->text, 0, 7);
+ } elseif ($c !== 7) {
+ throw new BCGParseException('ean8', 'Must contain 7 digits, the 8th digit is automatically added.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected function processChecksum() {
+ if ($this->checksumValue === false) { // Calculate the checksum only once
+ $this->calculateChecksum();
+ }
+
+ if ($this->checksumValue !== false) {
+ return $this->keys[$this->checksumValue];
+ }
+
+ return false;
+ }
+
+ /**
+ * Draws the extended bars on the image.
+ *
+ * @param resource $im
+ * @param int $plus
+ */
+ private function drawExtendedBars($im, $plus) {
+ $rememberX = $this->positionX;
+ $rememberH = $this->thickness;
+
+ // We increase the bars
+ $this->thickness = $this->thickness + intval($plus / $this->scale);
+ $this->positionX = 0;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ // Center Guard Bar
+ $this->positionX += 30;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ // Last Bars
+ $this->positionX += 30;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ $this->positionX = $rememberX;
+ $this->thickness = $rememberH;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGgs1128.barcode.php b/application/libraries/barcodegen/class/BCGgs1128.barcode.php
new file mode 100755
index 000000000..a3c1a5031
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGgs1128.barcode.php
@@ -0,0 +1,679 @@
+identifiersAi = array(
+ '00' => array(self::NUMERIC, 18, 18, true),
+ '01' => array(self::NUMERIC, 14, 14, true),
+ '02' => array(self::NUMERIC, 14, 14, true),
+ '10' => array(self::ALPHA_NUMERIC, 1, 20, false),
+ '11' => array(self::DATE_YYMMDD, 6, 6, false),
+ '12' => array(self::DATE_YYMMDD, 6, 6, false),
+ '13' => array(self::DATE_YYMMDD, 6, 6, false),
+ '15' => array(self::DATE_YYMMDD, 6, 6, false),
+ '17' => array(self::DATE_YYMMDD, 6, 6, false),
+ '20' => array(self::NUMERIC, 2, 2, false),
+ '21' => array(self::ALPHA_NUMERIC, 1, 20, false),
+ '240' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '241' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '250' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '251' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '253' => array(self::NUMERIC, 14, 30, false),
+ '30' => array(self::NUMERIC, 1, 8, false),
+ '310y' => array(self::NUMERIC, 6, 6, false),
+ '311y' => array(self::NUMERIC, 6, 6, false),
+ '312y' => array(self::NUMERIC, 6, 6, false),
+ '313y' => array(self::NUMERIC, 6, 6, false),
+ '314y' => array(self::NUMERIC, 6, 6, false),
+ '315y' => array(self::NUMERIC, 6, 6, false),
+ '316y' => array(self::NUMERIC, 6, 6, false),
+ '320y' => array(self::NUMERIC, 6, 6, false),
+ '321y' => array(self::NUMERIC, 6, 6, false),
+ '322y' => array(self::NUMERIC, 6, 6, false),
+ '323y' => array(self::NUMERIC, 6, 6, false),
+ '324y' => array(self::NUMERIC, 6, 6, false),
+ '325y' => array(self::NUMERIC, 6, 6, false),
+ '326y' => array(self::NUMERIC, 6, 6, false),
+ '327y' => array(self::NUMERIC, 6, 6, false),
+ '328y' => array(self::NUMERIC, 6, 6, false),
+ '329y' => array(self::NUMERIC, 6, 6, false),
+ '330y' => array(self::NUMERIC, 6, 6, false),
+ '331y' => array(self::NUMERIC, 6, 6, false),
+ '332y' => array(self::NUMERIC, 6, 6, false),
+ '333y' => array(self::NUMERIC, 6, 6, false),
+ '334y' => array(self::NUMERIC, 6, 6, false),
+ '335y' => array(self::NUMERIC, 6, 6, false),
+ '336y' => array(self::NUMERIC, 6, 6, false),
+ '337y' => array(self::NUMERIC, 6, 6, false),
+ '340y' => array(self::NUMERIC, 6, 6, false),
+ '341y' => array(self::NUMERIC, 6, 6, false),
+ '342y' => array(self::NUMERIC, 6, 6, false),
+ '343y' => array(self::NUMERIC, 6, 6, false),
+ '344y' => array(self::NUMERIC, 6, 6, false),
+ '345y' => array(self::NUMERIC, 6, 6, false),
+ '346y' => array(self::NUMERIC, 6, 6, false),
+ '347y' => array(self::NUMERIC, 6, 6, false),
+ '348y' => array(self::NUMERIC, 6, 6, false),
+ '349y' => array(self::NUMERIC, 6, 6, false),
+ '350y' => array(self::NUMERIC, 6, 6, false),
+ '351y' => array(self::NUMERIC, 6, 6, false),
+ '352y' => array(self::NUMERIC, 6, 6, false),
+ '353y' => array(self::NUMERIC, 6, 6, false),
+ '354y' => array(self::NUMERIC, 6, 6, false),
+ '355y' => array(self::NUMERIC, 6, 6, false),
+ '356y' => array(self::NUMERIC, 6, 6, false),
+ '357y' => array(self::NUMERIC, 6, 6, false),
+ '360y' => array(self::NUMERIC, 6, 6, false),
+ '361y' => array(self::NUMERIC, 6, 6, false),
+ '362y' => array(self::NUMERIC, 6, 6, false),
+ '363y' => array(self::NUMERIC, 6, 6, false),
+ '364y' => array(self::NUMERIC, 6, 6, false),
+ '365y' => array(self::NUMERIC, 6, 6, false),
+ '366y' => array(self::NUMERIC, 6, 6, false),
+ '367y' => array(self::NUMERIC, 6, 6, false),
+ '368y' => array(self::NUMERIC, 6, 6, false),
+ '369y' => array(self::NUMERIC, 6, 6, false),
+ '37' => array(self::NUMERIC, 1, 8, false),
+ '390y' => array(self::NUMERIC, 1, 15, false),
+ '391y' => array(self::NUMERIC, 4, 18, false),
+ '392y' => array(self::NUMERIC, 1, 15, false),
+ '393y' => array(self::NUMERIC, 4, 18, false),
+ '400' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '401' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '402' => array(self::NUMERIC, 17, 17, false),
+ '403' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '410' => array(self::NUMERIC, 13, 13, true),
+ '411' => array(self::NUMERIC, 13, 13, true),
+ '412' => array(self::NUMERIC, 13, 13, true),
+ '413' => array(self::NUMERIC, 13, 13, true),
+ '414' => array(self::NUMERIC, 13, 13, true),
+ '415' => array(self::NUMERIC, 13, 13, true),
+ '420' => array(self::ALPHA_NUMERIC, 1, 20, false),
+ '421' => array(self::ALPHA_NUMERIC, 4, 12, false),
+ '422' => array(self::NUMERIC, 3, 3, false),
+ '8001' => array(self::NUMERIC, 14, 14, false),
+ '8002' => array(self::ALPHA_NUMERIC, 1, 20, false),
+ '8003' => array(self::ALPHA_NUMERIC, 15, 30, false),
+ '8004' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '8005' => array(self::NUMERIC, 6, 6, false),
+ '8006' => array(self::NUMERIC, 18, 18, false),
+ '8007' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '8018' => array(self::NUMERIC, 18, 18, false),
+ '8020' => array(self::ALPHA_NUMERIC, 1, 25, false),
+ '8100' => array(self::NUMERIC, 6, 6, false),
+ '8101' => array(self::NUMERIC, 10, 10, false),
+ '8102' => array(self::NUMERIC, 2, 2, false),
+ '90' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '91' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '92' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '93' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '94' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '95' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '96' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '97' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '98' => array(self::ALPHA_NUMERIC, 1, 30, false),
+ '99' => array(self::ALPHA_NUMERIC, 1, 30, false)
+ );
+
+ $this->setStrictMode(true);
+ $this->setTilde(true);
+ $this->setAllowsUnknownIdentifier(false);
+ $this->setNoLengthLimit(false);
+ }
+
+ /**
+ * Gets the content checksum for an identifier.
+ * Do not pass the identifier code.
+ *
+ * @param string $content
+ * @return int
+ */
+ public static function getAiContentChecksum($content) {
+ return self::calculateChecksumMod10($content);
+ }
+
+ /**
+ * Enables or disables the strict mode.
+ *
+ * @param bool $strictMode
+ */
+ public function setStrictMode($strictMode) {
+ $this->strictMode = $strictMode;
+ }
+
+ /**
+ * Gets if the strict mode is activated.
+ *
+ * @return bool
+ */
+ public function getStrictMode() {
+ return $this->strictMode;
+ }
+
+ /**
+ * Allows unknown identifiers.
+ *
+ * @param bool $allow
+ */
+ public function setAllowsUnknownIdentifier($allow) {
+ $this->allowsUnknownIdentifier = (bool)$allow;
+ }
+
+ /**
+ * Gets if unkmown identifiers are allowed.
+ *
+ * @return bool
+ */
+ public function getAllowsUnknownIdentifier() {
+ return $this->allowsUnknownIdentifier;
+ }
+
+ /**
+ * Removes the limit of 48 characters.
+ *
+ * @param bool $noLengthLimit
+ */
+ public function setNoLengthLimit($noLengthLimit) {
+ $this->noLengthLimit = (bool)$noLengthLimit;
+ }
+
+ /**
+ * Gets if the limit of 48 characters is removed.
+ *
+ * @return bool
+ */
+ public function getNoLengthLimit() {
+ return $this->noLengthLimit;
+ }
+
+ /**
+ * Parses Text.
+ *
+ * @param string $text
+ */
+ public function parse($text) {
+ parent::parse($this->parseGs1128($text));
+ }
+
+ /**
+ * Formats data for gs1-128.
+ *
+ * @return string
+ */
+ private function formatGs1128() {
+ $formatedText = '~F1';
+ $formatedLabel = '';
+ $c = count($this->identifiersId);
+
+ for ($i = 0; $i < $c; $i++) {
+ if ($i > 0) {
+ $formatedLabel .= ' ';
+ }
+
+ if ($this->identifiersId[$i] !== null) {
+ $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 () char */
+ /* If we use the legacy mode, we always add a ~F1 () char between AIs */
+ if ($ai_data !== null) {
+ if ((strlen($this->identifiersContent[$i]) < $ai_data[self::MAXLENGTH] && ($i + 1) !== $c) || (!$this->strictMode && ($i + 1) !== $c)) {
+ $formatedText .= '~F1';
+ }
+ } elseif ($this->allowsUnknownIdentifier && $this->identifiersId[$i] === null && ($i + 1) !== $c) {
+ /* If this id is unknown, we add a ~F1 () char */
+ $formatedText .= '~F1';
+ }
+ }
+
+ if ($this->noLengthLimit === false && (strlen(str_replace('~F1', chr(29), $formatedText)) - 1) > self::MAX_GS1128_CHARS) {
+ throw new BCGParseException('gs1128', 'The barcode can\'t contain more than ' . self::MAX_GS1128_CHARS . ' characters.');
+ }
+
+ $this->label = $formatedLabel;
+ return $formatedText;
+ }
+
+ /**
+ * Parses the text to gs1-128.
+ *
+ * @param mixed $text
+ * @return mixed
+ */
+ private function parseGs1128($text) {
+ /* 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[self::ID]) || is_array($content[self::CONTENT])) {
+ throw new BCGParseException('gs1128', 'Double arrays can\'t contain arrays.');
+ } else {
+ $formatArray[] = '(' . $content[self::ID] . ')' . $content[self::CONTENT];
+ }
+ } else {
+ throw new BCGParseException('gs1128', 'Double arrays must contain 2 values.');
+ }
+ } 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;
+ }
+ }
+
+ return $this->formatGs1128();
+ }
+
+ /**
+ * Splits the id and the content for each application identifiers (AIs).
+ *
+ * @param string $text
+ * @param int $cmpt
+ * @return bool
+ */
+ private function parseContent($text) {
+ /* $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; */
+ $content = null;
+ $yAlreadySet = null;
+ $realNameId = null;
+ $separatorsFound = 0;
+ $checksumAdded = 0;
+ $decimalPointRemoved = 0;
+ $toParse = str_replace('~F1', chr(29), $text);
+ $nbCharToParse = strlen($toParse);
+ $nbCharId = 0;
+ $isFormated = $toParse[0] === '(' ? true : false;
+ $maxCharId = $isFormated ? self::MAX_ID_FORMATED : self::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) {
+ if ($this->allowsUnknownIdentifier === false) {
+ return false;
+ }
+
+ $id = null;
+ $nbCharId = 0;
+ $content = $toParse;
+ } else {
+ $nbCharId = strlen($id) + ($isFormated ? 2 : 0);
+ $n = min($this->identifiersAi[$realNameId][self::MAXLENGTH], $nbCharToParse);
+ $content = substr($toParse, $nbCharId, $n);
+ }
+
+ if ($id !== null) {
+ /* 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++;
+ }
+
+ if ($id !== null) {
+ /* 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;
+ return $this->parseContent($text);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks if an id exists.
+ *
+ * @param string $id
+ * @param bool $yAlreadySet
+ * @param string $realNameId
+ * @return bool
+ */
+ private function idExists($id, &$yAlreadySet, &$realNameId) {
+ $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
+ */
+ private function findIdFormated($id, &$yAlreadySet, &$realNameId) {
+ $pos = strpos($id, ')');
+ if ($pos === false) {
+ throw new BCGParseException('gs1128', 'Identifiers must have no more than 4 characters.');
+ } else {
+ if ($pos < 3) {
+ throw new BCGParseException('gs1128', 'Identifiers must have at least 2 characters.');
+ }
+
+ $id = substr($id, 1, $pos - 1);
+ if ($this->idExists($id, $yAlreadySet, $realNameId)) {
+ return $id;
+ }
+
+ if ($this->allowsUnknownIdentifier === false) {
+ throw new BCGParseException('gs1128', '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
+ */
+ private function findIdNotFormated($id, &$yAlreadySet, &$realNameId) {
+ $tofind = $id;
+
+ while (strlen($tofind) >= 2) {
+ if ($this->idExists($tofind, $yAlreadySet, $realNameId)) {
+ return $tofind;
+ } else {
+ $tofind = substr($tofind, 0, -1);
+ }
+ }
+
+ if ($this->allowsUnknownIdentifier === false) {
+ throw new BCGParseException('gs1128', '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
+ */
+ private function checkConformity(&$content, $id, $realNameId) {
+ switch ($this->identifiersAi[$realNameId][self::KIND_OF_DATA]) {
+ case self::NUMERIC:
+ $content = str_replace(',', '.', $content);
+ if (!preg_match("/^[0-9.]+$/", $content)) {
+ throw new BCGParseException('gs1128', 'The value of "' . $id . '" must be numerical.');
+ }
+
+ break;
+ case self::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) {
+ throw new BCGParseException('gs1128', 'The value of "' . $id . '" must be in YYMMDD format.');
+ }
+
+ break;
+ }
+
+ // We check the length of the content
+ $nbCharContent = strlen($content);
+ $checksumChar = 0;
+ $minlengthContent = $this->identifiersAi[$realNameId][self::MINLENGTH];
+ $maxlengthContent = $this->identifiersAi[$realNameId][self::MAXLENGTH];
+
+ if ($this->identifiersAi[$realNameId][self::CHECKSUM]) {
+ $checksumChar++;
+ }
+
+ if ($nbCharContent < ($minlengthContent - $checksumChar)) {
+ if ($minlengthContent === $maxlengthContent) {
+ throw new BCGParseException('gs1128', 'The value of "' . $id . '" must contain ' . $minlengthContent . ' character(s).');
+ } else {
+ throw new BCGParseException('gs1128', 'The value of "' . $id . '" must contain between ' . $minlengthContent . ' and ' . $maxlengthContent . ' character(s).');
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Verifies the checksum.
+ *
+ * @param string $content
+ * @param string $id
+ * @param int $realNameId
+ * @param int $checksumAdded
+ * @return bool
+ */
+ private function checkChecksum(&$content, $id, $realNameId, &$checksumAdded) {
+ if ($this->identifiersAi[$realNameId][self::CHECKSUM]) {
+ $nbCharContent = strlen($content);
+ $minlengthContent = $this->identifiersAi[$realNameId][self::MINLENGTH];
+ if ($nbCharContent === ($minlengthContent - 1)) {
+ /* we need to calculate the checksum */
+ $content .= self::getAiContentChecksum($content);
+ $checksumAdded++;
+ } elseif ($nbCharContent === $minlengthContent) {
+ /* we need to check the checksum */
+ $checksum = self::getAiContentChecksum(substr($content, 0, -1));
+ if (intval($content[$nbCharContent - 1]) !== $checksum) {
+ throw new BCGParseException('gs1128', 'The checksum of "(' . $id . ') ' . $content . '" must be: ' . $checksum);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks vars "y".
+ *
+ * @param string $content
+ * @param string $id
+ * @param bool $yAlreadySet
+ * @param int $decimalPointRemoved
+ * @return bool
+ */
+ private function checkVars(&$content, &$id, $yAlreadySet, &$decimalPointRemoved) {
+ $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) {
+ throw new BCGParseException('gs1128', 'If you do not use any "y" variable, you have to insert a whole number.');
+ }
+ } elseif ($yAlreadySet !== null) {
+ /* We need to replace the "y" var with the position of the decimal point */
+ $pos = strpos($content, '.');
+ if ($pos === false) {
+ $pos = $nbCharContent - 1;
+ }
+
+ $id = str_replace('y', $nbCharContent - ($pos + 1), strtolower($id));
+ $content = str_replace('.', '', $content);
+ $decimalPointRemoved++;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checksum Mod10.
+ *
+ * @param int $content
+ * @return int
+ */
+ private static function calculateChecksumMod10($content) {
+ // 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;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGi25.barcode.php b/application/libraries/barcodegen/class/BCGi25.barcode.php
new file mode 100755
index 000000000..871aeabd5
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGi25.barcode.php
@@ -0,0 +1,203 @@
+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);
+ $this->setRatio(2);
+ }
+
+ /**
+ * Sets the checksum.
+ *
+ * @param bool $checksum
+ */
+ public function setChecksum($checksum) {
+ $this->checksum = (bool)$checksum;
+ }
+
+ /**
+ * Sets the ratio of the black bar compared to the white bars.
+ *
+ * @param int $ratio
+ */
+ public function setRatio($ratio) {
+ $this->ratio = $ratio;
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ $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, $this->changeBars($temp_bar), true);
+ }
+
+ // Ending Code
+ $this->drawChar($im, $this->changeBars('100'), true);
+ $this->drawText($im, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $textlength = (3 + ($this->ratio + 1) * 2) * strlen($this->text);
+ $startlength = 4;
+ $checksumlength = 0;
+ if ($this->checksum === true) {
+ $checksumlength = (3 + ($this->ratio + 1) * 2);
+ }
+
+ $endlength = 2 + ($this->ratio + 1);
+
+ $w += $startlength + $textlength + $checksumlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('i25', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('i25', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ // Must be even
+ if ($c % 2 !== 0 && $this->checksum === false) {
+ throw new BCGParseException('i25', 'i25 must contain an even amount of digits if checksum is false.');
+ } elseif ($c % 2 === 0 && $this->checksum === true) {
+ throw new BCGParseException('i25', 'i25 must contain an odd amount of digits if checksum is true.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected function processChecksum() {
+ if ($this->checksumValue === false) { // Calculate the checksum only once
+ $this->calculateChecksum();
+ }
+
+ if ($this->checksumValue !== false) {
+ return $this->keys[$this->checksumValue];
+ }
+
+ return false;
+ }
+
+ /**
+ * Changes the size of the bars based on the ratio
+ *
+ * @param string $in
+ * @return string
+ */
+ private function changeBars($in) {
+ if ($this->ratio > 1) {
+ $c = strlen($in);
+ for ($i = 0; $i < $c; $i++) {
+ $in[$i] = $in[$i] === '1' ? $this->ratio : $in[$i];
+ }
+ }
+
+ return $in;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGintelligentmail.barcode.php b/application/libraries/barcodegen/class/BCGintelligentmail.barcode.php
new file mode 100755
index 000000000..4226abeea
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGintelligentmail.barcode.php
@@ -0,0 +1,649 @@
+setQuietZone(true);
+ $this->setThickness(9);
+ }
+
+ /**
+ * Gets the Quiet zone.
+ *
+ * @return bool
+ */
+ public function getQuietZone() {
+ return $this->quietZone;
+ }
+
+ /**
+ * Sets the Quiet zone.
+ *
+ * @param bool $quietZone
+ */
+ public function setQuietZone($quietZone) {
+ $this->quietZone = (bool)$quietZone;
+ }
+
+ /**
+ * Sets the tracking code.
+ *
+ * @param int $barcodeIdentifier 2-digit number. 2nd digit must be 0-4
+ * @param int $serviceTypeIdentifier 3 digits
+ * @param int $mailerIdentifier 6 or 9 digits
+ * @param int $serialNumber 9 (if mailerId is 6) or 6 digits (if mailerId is 9)
+ */
+ public function setTrackingCode($barcodeIdentifier, $serviceTypeIdentifier, $mailerIdentifier, $serialNumber) {
+ $barcodeIdentifier = (string)(int)$barcodeIdentifier;
+ $serviceTypeIdentifier = (int)$serviceTypeIdentifier;
+ $mailerIdentifier = (int)$mailerIdentifier;
+ $serialNumber = (string)(int)$serialNumber;
+
+ $barcodeIdentifier = str_pad($barcodeIdentifier, 2, '0', STR_PAD_LEFT);
+
+ if (strlen($barcodeIdentifier) !== 2) {
+ throw new BCGArgumentException('Barcode Identifier must contain 2 digits.', 'barcodeIdentifier');
+ }
+
+ $barcodeIdentifierSecondNumber = $barcodeIdentifier[1];
+ if ($barcodeIdentifierSecondNumber !== '0' && $barcodeIdentifierSecondNumber !== '1' && $barcodeIdentifierSecondNumber !== '2' && $barcodeIdentifierSecondNumber !== '3' && $barcodeIdentifierSecondNumber !== '4') {
+ throw new BCGArgumentException('Barcode Identifier second digit must be a number between 0 and 4.', 'barcodeIdentifier');
+ }
+
+ if ($serviceTypeIdentifier < 0 || $serviceTypeIdentifier > 999) {
+ throw new BCGArgumentException('Service Type Identifier must be between 0 and 999.', 'serviceTypeIdentifier');
+ }
+
+ $mailerIdentifierLength = 6;
+ if ($mailerIdentifier > 899999) {
+ $mailerIdentifierLength = 9;
+ }
+
+ if ($mailerIdentifierLength === 9 && strlen($serialNumber) > 6) {
+ throw new BCGArgumentException('If the Serial Number has more than 6 digits, the Mailer Identifier must be lower than 900000.', 'mailerIdentifier');
+ }
+
+ if ($mailerIdentifierLength === 9) {
+ if ($mailerIdentifierLength < 0 || $mailerIdentifier > 999999999) {
+ throw new BCGArgumentException('Mailer Identifier must be between 0 and 999999999.', 'mailerIdentifier');
+ }
+ }
+
+ $this->barcodeIdentifier = $barcodeIdentifier;
+ $this->serviceTypeIdentifier = str_pad($serviceTypeIdentifier, 3, '0', STR_PAD_LEFT);
+ $this->mailerIdentifier = str_pad($mailerIdentifier, $mailerIdentifierLength, '0', STR_PAD_LEFT);
+ $this->serialNumber = str_pad((int)$serialNumber, $mailerIdentifierLength === 6 ? 9 : 6, '0', STR_PAD_LEFT);
+ }
+
+ /**
+ * Parses the text before displaying it.
+ *
+ * @param mixed $text
+ */
+ public function parse($text) {
+ parent::parse($text);
+
+ $number = self::executeStep1($this->text, $this->barcodeIdentifier, $this->serviceTypeIdentifier, $this->mailerIdentifier, $this->serialNumber);
+ $crc = self::executeStep2($number);
+ $codewords = self::executeStep3($number);
+ $codewords = self::executeStep4($codewords, $crc);
+ $characters = self::executeStep5($codewords, $crc);
+ $this->data = self::executeStep6($characters);
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ if ($this->quietZone) {
+ $this->positionX += 9;
+ }
+
+ $c = strlen($this->data);
+ for ($i = 0; $i < $c; $i++) {
+ $this->drawChar($im, $this->data[$i]);
+ }
+
+ $this->drawText($im, 0, 0, $this->positionX, $this->thickness + ($this->quietZone ? 4 : 0));
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $w += 65 * 3;
+ $h += $this->thickness;
+
+ // We remove the white on the right
+ $w -= 1.56;
+
+ if ($this->quietZone) {
+ $w += 18;
+ $h += 4;
+ }
+
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ // Tracking must have been entered
+ if ($this->barcodeIdentifier === null || $this->serviceTypeIdentifier === null || $this->mailerIdentifier === null || $this->serialNumber === null) {
+ throw new BCGParseException('intelligentmail', 'The tracking code must be set before calling the parse method.');
+ }
+
+ // Checking if all chars are allowed
+ $match = array();
+ if (preg_match('/[^0-9]/', $this->text, $match)) {
+ throw new BCGParseException('intelligentmail', 'The character \'' . $match[0] . '\' is not allowed.');
+ }
+
+ // Must contain 0, 5, 9 or 11 chars
+ $c = strlen($this->text);
+ if ($c !== 0 && $c !== 5 && $c !== 9 && $c !== 11) {
+ throw new BCGParseException('intelligentmail', 'Must contain 0, 5, 9, or 11 characters.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method for drawing special barcode.
+ *
+ * @param resource $im
+ * @param string $code
+ * @param boolean $startBar
+ */
+ protected function drawChar($im, $code, $startBar = true) {
+ $y1 = 0;
+ $y2 = 0;
+ switch ($code) {
+ case 'A':
+ $y1 = 0;
+ $y2 = $this->thickness - ($this->thickness / 2.5);
+ break;
+ case 'D':
+ $y1 = 3.096;
+ $y2 = $this->thickness - 1;
+ break;
+ case 'F':
+ $y1 = 0;
+ $y2 = $this->thickness - 1;
+ break;
+ case 'T':
+ $y1 = 3.096;
+ $y2 = $this->thickness - ($this->thickness / 2.5);
+ break;
+ }
+
+ if ($this->quietZone) {
+ $y1 += 2;
+ $y2 += 2;
+ }
+
+ $this->drawFilledRectangle($im, $this->positionX, $y1, $this->positionX + 0.44, $y2, BCGBarcode::COLOR_FG);
+ $this->positionX += 3;
+ }
+
+ /**
+ * Executes Step 1: Conversion of Data Fields into Binary Data
+ *
+ * @param string $text
+ * @param string $barcodeIdentifier
+ * @param string $serviceTypeIdentifier
+ * @param string $mailerIdentifier
+ * @param string $serialNumber
+ * @return string BCNumber
+ */
+ private static function executeStep1($text, $barcodeIdentifier, $serviceTypeIdentifier, $mailerIdentifier, $serialNumber) {
+ $number = self::conversionRoutingCode($text);
+ $number = self::conversionTrackingCode($number, $barcodeIdentifier, $serviceTypeIdentifier, $mailerIdentifier, $serialNumber);
+
+ return $number;
+ }
+
+ /**
+ * Executes Step 2: Generation of 11-Bit CRC on Binary Data
+ *
+ * @param $number BCNumber
+ * @return int
+ */
+ private static function executeStep2($number) {
+ $byteArray = str_pad(self::bcdecuc($number), 13, chr(0), STR_PAD_LEFT);
+
+ $generatorPolynomial = 0x0f35;
+ $frameCheckSequence = 0x07ff;
+ $data = 0;
+ $byteIndex = 0;
+ $bit = 0;
+
+ $data = (ord($byteArray[$byteIndex]) << 5) & 0xffff;
+ for ($bit = 2; $bit < 8; $bit++) {
+ if (($frameCheckSequence ^ $data) & 0x400) {
+ $frameCheckSequence = ($frameCheckSequence << 1) ^ $generatorPolynomial;
+ } else {
+ $frameCheckSequence = ($frameCheckSequence << 1);
+ }
+
+ $frameCheckSequence &= 0x7ff;
+ $data <<= 1;
+ $data &= 0xffff;
+ }
+
+ for ($byteIndex = 1; $byteIndex < 13; $byteIndex++) {
+ $data = (ord($byteArray[$byteIndex]) << 3) & 0xffff;
+ for ($bit = 0; $bit < 8; $bit++) {
+ if (($frameCheckSequence ^ $data) & 0x0400) {
+ $frameCheckSequence = ($frameCheckSequence << 1) ^ $generatorPolynomial;
+ } else {
+ $frameCheckSequence = ($frameCheckSequence << 1);
+ }
+
+ $frameCheckSequence &= 0x7ff;
+ $data <<= 1;
+ $data &= 0xffff;
+ }
+ }
+
+ return $frameCheckSequence;
+ }
+
+ /**
+ * Executes Step 3: Conversion from Binary Data to Codewords
+ *
+ * @param string $number BCNumber
+ * @return int[]
+ */
+ private static function executeStep3($number) {
+ $codewords = array();
+ $codewords[9] = (int)bcmod($number, '636');
+ $number = bcdiv($number, '636', 0);
+
+ for ($i = 8; $i >= 0; $i--) {
+ $codewords[$i] = (int)bcmod($number, '1365');
+ $number = bcdiv($number, '1365', 0);
+ }
+
+ return $codewords;
+ }
+
+ /**
+ * Executes Step 4: Inserting Additional Information into Codewords
+ *
+ * @param int[] $codewords
+ * @param int $crc
+ * @return int[]
+ */
+ private static function executeStep4($codewords, $crc) {
+ $codewords[9] *= 2;
+ if ($crc & 0x400) {
+ $codewords[0] += 659;
+ }
+
+ return $codewords;
+ }
+
+ /**
+ * Executes Step 5: Conversion from Codewords to Characters
+ *
+ * @param int[] $codewords
+ * @param int $crc
+ * @return int[]
+ */
+ private static function executeStep5($codewords, $crc) {
+ $characters = array();
+ for ($i = 0; $i < 10; $i++) {
+ if ($codewords[$i] <= 1286) {
+ $characters[$i] = self::$characterTable1[$codewords[$i]];
+ } else {
+ $characters[$i] = self::$characterTable2[$codewords[$i] - 1287];
+ }
+ }
+
+ for ($i = 0; $i < 10; $i++) {
+ $mask = 1 << $i;
+ if ($crc & $mask) {
+ $characters[$i] ^= 0x1fff;
+ }
+ }
+
+ return $characters;
+ }
+
+ /**
+ * Executes Step 6: Conversion from Characters to the Intelligent Mail Barcode
+ *
+ * @param int[] $characters
+ * @return string
+ */
+ private static function executeStep6($characters) {
+ $bars = '';
+ for ($i = 0; $i < 65; $i++) {
+ $barPosition = self::$barPositions[$i];
+ $descender = $barPosition[0];
+ $ascender = $barPosition[1];
+ $extenderDescender = !!($characters[$descender[0]] & (1 << $descender[1]));
+ $extenderAscender = !!($characters[$ascender[0]] & (1 << $ascender[1]));
+
+ if ($extenderDescender && $extenderAscender) {
+ $bars .= 'F';
+ } elseif ($extenderDescender) {
+ $bars .= 'D';
+ } elseif ($extenderAscender) {
+ $bars .= 'A';
+ } else {
+ $bars .= 'T';
+ }
+ }
+
+ return $bars;
+ }
+
+ /**
+ * Converts the routing code zipcode.
+ *
+ * @param string $zipcode
+ * @return string BCNumber
+ */
+ private static function conversionRoutingCode($zipcode) {
+ $number = $zipcode;
+ switch (strlen($zipcode)) {
+ case 11:
+ $number = bcadd($number, '1000000000', 0);
+ case 9:
+ $number = bcadd($number, '100000', 0);
+ case 5:
+ $number = bcadd($number, '1', 0);
+ default:
+ return $number;
+ }
+ }
+
+ /**
+ * Converts the tracking code number.
+ *
+ * @param string $number BCNumber
+ * @param string $barcodeIdentifier
+ * @param string $serviceTypeIdentifier
+ * @param string $mailerIdentifier
+ * @param string $serialNumber
+ * @return string BCNumber
+ */
+ private static function conversionTrackingCode($number, $barcodeIdentifier, $serviceTypeIdentifier, $mailerIdentifier, $serialNumber) {
+ $number = bcmul($number, 10, 0);
+ $number = bcadd($number, $barcodeIdentifier[0], 0);
+ $number = bcmul($number, 5, 0);
+ $number = bcadd($number, $barcodeIdentifier[1], 0);
+
+ $temp = $serviceTypeIdentifier . $mailerIdentifier . $serialNumber;
+ for ($i = 0; $i < 18; $i++) {
+ $number = bcmul($number, 10, 0);
+ $number = bcadd($number, $temp[$i], 0);
+ }
+
+ return $number;
+ }
+
+ /**
+ * Transforms a BCNumber into unsigned char*.
+ *
+ * @param string $dec BCNumber
+ * @param string
+ */
+ private static function bcdecuc($dec) {
+ $last = bcmod($dec, 256);
+ $remain = bcdiv(bcsub($dec, $last), 256, 0);
+
+ if ($remain == 0) {
+ return pack('C', $last);
+ } else {
+ return self::bcdecuc($remain) . pack('C', $last);
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGisbn.barcode.php b/application/libraries/barcodegen/class/BCGisbn.barcode.php
new file mode 100755
index 000000000..cba00d6c2
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGisbn.barcode.php
@@ -0,0 +1,164 @@
+setGS1($gs1);
+ }
+
+ /**
+ * Adds the default label.
+ */
+ protected function addDefaultLabel() {
+ if ($this->isDefaultEanLabelEnabled()) {
+ $isbn = $this->createISBNText();
+ $font = $this->font;
+
+ $topLabel = new BCGLabel($isbn, $font, BCGLabel::POSITION_TOP, BCGLabel::ALIGN_CENTER);
+
+ $this->addLabel($topLabel);
+ }
+
+ parent::addDefaultLabel();
+ }
+
+ /**
+ * 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
+ */
+ public function setGS1($gs1) {
+ $gs1 = (int)$gs1;
+ if ($gs1 !== self::GS1_AUTO && $gs1 !== self::GS1_PREFIX978 && $gs1 !== self::GS1_PREFIX979) {
+ throw new BCGArgumentException('The GS1 argument must be BCGisbn::GS1_AUTO, BCGisbn::GS1_PREFIX978, or BCGisbn::GS1_PREFIX979', 'gs1');
+ }
+
+ $this->gs1 = $gs1;
+ }
+
+ /**
+ * Check chars allowed.
+ */
+ protected function checkCharsAllowed() {
+ $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') {
+ throw new BCGParseException('isbn', 'The character \'' . $this->text[9] . '\' is not allowed.');
+ }
+
+ // Drop the last char
+ $this->text = substr($this->text, 0, 9);
+ }
+
+ return parent::checkCharsAllowed();
+ }
+
+ /**
+ * Check correct length.
+ */
+ protected function checkCorrectLength() {
+ $c = strlen($this->text);
+
+ // If we have 13 chars just flush the last one
+ if ($c === 13) {
+ $this->text = substr($this->text, 0, 12);
+ } 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') {
+ throw new BCGParseException('isbn', 'The character \'' . $this->text[9] . '\' is not allowed.');
+ }
+
+ $this->text = substr($this->text, 0, 9);
+ }
+
+ if ($this->gs1 === self::GS1_AUTO || $this->gs1 === self::GS1_PREFIX978) {
+ $this->text = '978' . $this->text;
+ } elseif ($this->gs1 === self::GS1_PREFIX979) {
+ $this->text = '979' . $this->text;
+ }
+ } elseif ($c !== 12) {
+ throw new BCGParseException('isbn', 'The code parsed must be 9, 10, 12, or 13 digits long.');
+ }
+ }
+
+ /**
+ * Creates the ISBN text.
+ *
+ * @return string
+ */
+ private function createISBNText() {
+ $isbn = '';
+ if (!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();
+ $isbn = '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'; // Changing type
+ }
+
+ $isbn = 'ISBN ' . substr($this->text, 0, 9) . '-' . $checksum;
+ }
+ }
+
+ return $isbn;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGmsi.barcode.php b/application/libraries/barcodegen/class/BCGmsi.barcode.php
new file mode 100755
index 000000000..92bb77ff9
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGmsi.barcode.php
@@ -0,0 +1,184 @@
+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);
+ }
+
+ /**
+ * Sets how many checksums we display. 0 to 2.
+ *
+ * @param int $checksum
+ */
+ public function setChecksum($checksum) {
+ $checksum = intval($checksum);
+ if ($checksum < 0 && $checksum > 2) {
+ throw new BCGArgumentException('The checksum must be between 0 and 2 included.', 'checksum');
+ }
+
+ $this->checksum = $checksum;
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ // 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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $textlength = 12 * strlen($this->text);
+ $startlength = 3;
+ $checksumlength = $this->checksum * 12;
+ $endlength = 4;
+
+ $w += $startlength + $textlength + $checksumlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('msi', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('msi', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected 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;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGothercode.barcode.php b/application/libraries/barcodegen/class/BCGothercode.barcode.php
new file mode 100755
index 000000000..bb7e6b0d8
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGothercode.barcode.php
@@ -0,0 +1,88 @@
+keys = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ $this->drawChar($im, $this->text, true);
+ $this->drawText($im, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Gets the label.
+ * If the label was set to BCGBarcode1D::AUTO_LABEL, the label will display the value from the text parsed.
+ *
+ * @return string
+ */
+ public function getLabel() {
+ $label = $this->label;
+ if ($this->label === BCGBarcode1D::AUTO_LABEL) {
+ $label = '';
+ }
+
+ return $label;
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $array = str_split($this->text, 1);
+ $textlength = array_sum($array) + count($array);
+
+ $w += $textlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('othercode', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('othercode', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ parent::validate();
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGpostnet.barcode.php b/application/libraries/barcodegen/class/BCGpostnet.barcode.php
new file mode 100755
index 000000000..cb0eac2a0
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGpostnet.barcode.php
@@ -0,0 +1,138 @@
+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 */
+ );
+
+ $this->setThickness(9);
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ // Checksum
+ $checksum = 0;
+ $c = strlen($this->text);
+ 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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $c = strlen($this->text);
+ $startlength = 3;
+ $textlength = $c * 5 * 3;
+ $checksumlength = 5 * 3;
+ $endlength = 3;
+
+ // We remove the white on the right
+ $removelength = -1.56;
+
+ $w += $startlength + $textlength + $checksumlength + $endlength + $removelength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('postnet', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('postnet', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ // Must contain 5, 9 or 11 chars
+ if ($c !== 5 && $c !== 9 && $c !== 11) {
+ throw new BCGParseException('postnet', 'Must contain 5, 9, or 11 characters.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method for drawing special barcode.
+ *
+ * @param resource $im
+ * @param string $code
+ * @param boolean $startBar
+ */
+ protected function drawChar($im, $code, $startBar = true) {
+ $c = strlen($code);
+ for ($i = 0; $i < $c; $i++) {
+ if ($code[$i] === '0') {
+ $posY = $this->thickness - ($this->thickness / 2.5);
+ } else {
+ $posY = 0;
+ }
+
+ $this->drawFilledRectangle($im, $this->positionX, $posY, $this->positionX + 0.44, $this->thickness - 1, BCGBarcode::COLOR_FG);
+ $this->positionX += 3;
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGs25.barcode.php b/application/libraries/barcodegen/class/BCGs25.barcode.php
new file mode 100755
index 000000000..6dc10e27e
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGs25.barcode.php
@@ -0,0 +1,170 @@
+ 1/3 or 1/2 for the big bar
+ *
+ *--------------------------------------------------------------------
+ * Copyright (C) Jean-Sebastien Goupil
+ * http://www.barcodephp.com
+ */
+include_once('BCGParseException.php');
+include_once('BCGBarcode1D.php');
+
+class BCGs25 extends BCGBarcode1D {
+ private $checksum;
+
+ /**
+ * Constructor.
+ */
+ public function __construct() {
+ parent::__construct();
+
+ $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);
+ }
+
+ /**
+ * Sets if we display the checksum.
+ *
+ * @param bool $checksum
+ */
+ public function setChecksum($checksum) {
+ $this->checksum = (bool)$checksum;
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ $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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $c = strlen($this->text);
+ $startlength = 8;
+ $textlength = $c * 14;
+ $checksumlength = 0;
+ if ($c % 2 !== 0) {
+ $checksumlength = 14;
+ }
+
+ $endlength = 7;
+
+ $w += $startlength + $textlength + $checksumlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('s25', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('s25', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ // Must be even
+ if ($c % 2 !== 0 && $this->checksum === false) {
+ throw new BCGParseException('s25', 's25 must contain an even amount of digits if checksum is false.');
+ } elseif ($c % 2 === 0 && $this->checksum === true) {
+ throw new BCGParseException('s25', 's25 must contain an odd amount of digits if checksum is true.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected function processChecksum() {
+ if ($this->checksumValue === false) { // Calculate the checksum only once
+ $this->calculateChecksum();
+ }
+
+ if ($this->checksumValue !== false) {
+ return $this->keys[$this->checksumValue];
+ }
+
+ return false;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGupca.barcode.php b/application/libraries/barcodegen/class/BCGupca.barcode.php
new file mode 100755
index 000000000..828bb8f07
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGupca.barcode.php
@@ -0,0 +1,146 @@
+text = '0' . $this->text; // We will remove it at the end... don't worry
+
+ parent::draw($im);
+
+ // We remove the 0 in front, as we said :)
+ $this->text = substr($this->text, 1);
+ }
+
+ /**
+ * Draws the extended bars on the image.
+ *
+ * @param resource $im
+ * @param int $plus
+ */
+ protected function drawExtendedBars($im, $plus) {
+ $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 + intval($plus / $this->scale);
+ $this->positionX = 0;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ // Attemping to increase the 2 following bars
+ $this->positionX += 1;
+ $temp_value = $this->findCode($temp_text[1]);
+ $this->drawChar($im, $temp_value, false);
+
+ // Center Guard Bar
+ $this->positionX += 36;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ // 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, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ $this->positionX = $rememberX;
+ $this->thickness = $rememberH;
+ }
+
+ /**
+ * Adds the default label.
+ */
+ protected function addDefaultLabel() {
+ if ($this->isDefaultEanLabelEnabled()) {
+ $this->processChecksum();
+ $label = $this->getLabel();
+ $font = $this->font;
+
+ $this->labelLeft = new BCGLabel(substr($label, 0, 1), $font, BCGLabel::POSITION_LEFT, BCGLabel::ALIGN_BOTTOM);
+ $this->labelLeft->setSpacing(4 * $this->scale);
+
+ $this->labelCenter1 = new BCGLabel(substr($label, 1, 5), $font, BCGLabel::POSITION_BOTTOM, BCGLabel::ALIGN_LEFT);
+ $labelCenter1Dimension = $this->labelCenter1->getDimension();
+ $this->labelCenter1->setOffset(($this->scale * 44 - $labelCenter1Dimension[0]) / 2 + $this->scale * 6);
+
+ $this->labelCenter2 = new BCGLabel(substr($label, 6, 5), $font, BCGLabel::POSITION_BOTTOM, BCGLabel::ALIGN_LEFT);
+ $this->labelCenter2->setOffset(($this->scale * 44 - $labelCenter1Dimension[0]) / 2 + $this->scale * 45);
+
+ $this->labelRight = new BCGLabel($this->keys[$this->checksumValue], $font, BCGLabel::POSITION_RIGHT, BCGLabel::ALIGN_BOTTOM);
+ $this->labelRight->setSpacing(4 * $this->scale);
+
+ if ($this->alignLabel) {
+ $labelDimension = $this->labelCenter1->getDimension();
+ $this->labelLeft->setOffset($labelDimension[1]);
+ $this->labelRight->setOffset($labelDimension[1]);
+ } else {
+ $labelDimension = $this->labelLeft->getDimension();
+ $this->labelLeft->setOffset($labelDimension[1] / 2);
+ $labelDimension = $this->labelLeft->getDimension();
+ $this->labelRight->setOffset($labelDimension[1] / 2);
+ }
+
+ $this->addLabel($this->labelLeft);
+ $this->addLabel($this->labelCenter1);
+ $this->addLabel($this->labelCenter2);
+ $this->addLabel($this->labelRight);
+ }
+ }
+
+ /**
+ * Check correct length.
+ */
+ protected function checkCorrectLength() {
+ // If we have 12 chars, just flush the last one without throwing anything
+ $c = strlen($this->text);
+ if ($c === 12) {
+ $this->text = substr($this->text, 0, 11);
+ } elseif ($c !== 11) {
+ throw new BCGParseException('upca', 'Must contain 11 digits, the 12th digit is automatically added.');
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGupce.barcode.php b/application/libraries/barcodegen/class/BCGupce.barcode.php
new file mode 100755
index 000000000..f22c408cd
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGupce.barcode.php
@@ -0,0 +1,336 @@
+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 */
+ )
+ );
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ $this->calculateChecksum();
+
+ // Starting Code
+ $this->drawChar($im, '000', true);
+ $c = strlen($this->upce);
+ for ($i = 0; $i < $c; $i++) {
+ $this->drawChar($im, self::inverse($this->findCode($this->upce[$i]), $this->codeParity[intval($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] . $this->upce;
+ $this->drawText($im, 0, 0, $this->positionX, $this->thickness);
+
+ if ($this->isDefaultEanLabelEnabled()) {
+ $dimension = $this->labelCenter->getDimension();
+ $this->drawExtendedBars($im, $dimension[1] - 2);
+ }
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $startlength = 3;
+ $centerlength = 5;
+ $textlength = 6 * 7;
+ $endlength = 1;
+
+ $w += $startlength + $centerlength + $textlength + $endlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Adds the default label.
+ */
+ protected function addDefaultLabel() {
+ if ($this->isDefaultEanLabelEnabled()) {
+ $this->processChecksum();
+ $font = $this->font;
+
+ $this->labelLeft = new BCGLabel(substr($this->text, 0, 1), $font, BCGLabel::POSITION_LEFT, BCGLabel::ALIGN_BOTTOM);
+ $labelLeftDimension = $this->labelLeft->getDimension();
+ $this->labelLeft->setSpacing(8);
+ $this->labelLeft->setOffset($labelLeftDimension[1] / 2);
+
+ $this->labelCenter = new BCGLabel($this->upce, $font, BCGLabel::POSITION_BOTTOM, BCGLabel::ALIGN_LEFT);
+ $labelCenterDimension = $this->labelCenter->getDimension();
+ $this->labelCenter->setOffset(($this->scale * 46 - $labelCenterDimension[0]) / 2 + $this->scale * 2);
+
+ $this->labelRight = new BCGLabel($this->keys[$this->checksumValue], $font, BCGLabel::POSITION_RIGHT, BCGLabel::ALIGN_BOTTOM);
+ $labelRightDimension = $this->labelRight->getDimension();
+ $this->labelRight->setSpacing(8);
+ $this->labelRight->setOffset($labelRightDimension[1] / 2);
+
+ $this->addLabel($this->labelLeft);
+ $this->addLabel($this->labelCenter);
+ $this->addLabel($this->labelRight);
+ }
+ }
+
+ /**
+ * Checks if the default ean label is enabled.
+ *
+ * @return bool
+ */
+ protected function isDefaultEanLabelEnabled() {
+ $label = $this->getLabel();
+ $font = $this->font;
+ return $label !== null && $label !== '' && $font !== null && $this->defaultLabel !== null;
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('upce', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('upce', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ // Must contain 11 chars
+ // Must contain 6 chars (if starting with upce directly)
+ // First Chars must be 0 or 1
+ if ($c !== 11 && $c !== 6) {
+ throw new BCGParseException('upce', 'You must provide a UPC-A (11 characters) or a UPC-E (6 characters).');
+ } elseif ($this->text[0] !== '0' && $this->text[0] !== '1' && $c !== 6) {
+ throw new BCGParseException('upce', 'UPC-A must start with 0 or 1 to be converted to UPC-E.');
+ }
+
+ // Convert part
+ $this->upce = '';
+ if ($c !== 6) {
+ // Checking if UPC-A is convertible
+ $temp1 = substr($this->text, 3, 3);
+ if ($temp1 === '000' || $temp1 === '100' || $temp1 === '200') { // manufacturer code ends with 100, 200 or 300
+ if (substr($this->text, 6, 2) === '00') { // Product must start with 00
+ $this->upce = substr($this->text, 1, 2) . substr($this->text, 8, 3) . substr($this->text, 3, 1);
+ }
+ } elseif (substr($this->text, 4, 2) === '00') { // manufacturer code ends with 00
+ if (substr($this->text, 6, 3) === '000') { // Product must start with 000
+ $this->upce = substr($this->text, 1, 3) . substr($this->text, 9, 2) . '3';
+ }
+ } elseif (substr($this->text, 5, 1) === '0') { // manufacturer code ends with 0
+ if (substr($this->text, 6, 4) === '0000') { // Product must start with 0000
+ $this->upce = substr($this->text, 1, 4) . substr($this->text, 10, 1) . '4';
+ }
+ } else { // No zero leading at manufacturer code
+ $temp2 = intval(substr($this->text, 10, 1));
+ if (substr($this->text, 6, 4) === '0000' && $temp2 >= 5 && $temp2 <= 9) { // Product must start with 0000 and must end by 5, 6, 7, 8 or 9
+ $this->upce = substr($this->text, 1, 5) . substr($this->text, 10, 1);
+ }
+ }
+ } else {
+ $this->upce = $this->text;
+ }
+
+ if ($this->upce === '') {
+ throw new BCGParseException('upce', 'Your UPC-A can\'t be converted to UPC-E.');
+ }
+
+ if ($c === 6) {
+ $upca = '';
+
+ // 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;
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected function processChecksum() {
+ if ($this->checksumValue === false) { // Calculate the checksum only once
+ $this->calculateChecksum();
+ }
+
+ if ($this->checksumValue !== false) {
+ return $this->keys[$this->checksumValue];
+ }
+
+ return false;
+ }
+
+ /**
+ * Draws the extended bars on the image.
+ *
+ * @param resource $im
+ * @param int $plus
+ */
+ protected function drawExtendedBars($im, $plus) {
+ $rememberX = $this->positionX;
+ $rememberH = $this->thickness;
+
+ // We increase the bars
+ $this->thickness = $this->thickness + intval($plus / $this->scale);
+ $this->positionX = 0;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ // Last Bars
+ $this->positionX += 46;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+ $this->positionX += 2;
+ $this->drawSingleBar($im, BCGBarcode::COLOR_FG);
+
+ $this->positionX = $rememberX;
+ $this->thickness = $rememberH;
+ }
+
+ /**
+ * Inverses the string when the $inverse parameter is equal to 1.
+ *
+ * @param string $text
+ * @param int $inverse
+ * @return string
+ */
+ private static function inverse($text, $inverse = 1) {
+ if ($inverse === 1) {
+ $text = strrev($text);
+ }
+
+ return $text;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGupcext2.barcode.php b/application/libraries/barcodegen/class/BCGupcext2.barcode.php
new file mode 100755
index 000000000..3f1be1655
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGupcext2.barcode.php
@@ -0,0 +1,138 @@
+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 */
+ );
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ // Starting Code
+ $this->drawChar($im, '001', true);
+
+ // Code
+ for ($i = 0; $i < 2; $i++) {
+ $this->drawChar($im, self::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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $startlength = 4;
+ $textlength = 2 * 7;
+ $intercharlength = 2;
+
+ $w += $startlength + $textlength + $intercharlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Adds the default label.
+ */
+ protected function addDefaultLabel() {
+ parent::addDefaultLabel();
+
+ if ($this->defaultLabel !== null) {
+ $this->defaultLabel->setPosition(BCGLabel::POSITION_TOP);
+ }
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('upcext2', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('upcext2', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ // Must contain 2 digits
+ if ($c !== 2) {
+ throw new BCGParseException('upcext2', 'Must contain 2 digits.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Inverses the string when the $inverse parameter is equal to 1.
+ *
+ * @param string $text
+ * @param int $inverse
+ * @return string
+ */
+ private static function inverse($text, $inverse = 1) {
+ if ($inverse === 1) {
+ $text = strrev($text);
+ }
+
+ return $text;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/BCGupcext5.barcode.php b/application/libraries/barcodegen/class/BCGupcext5.barcode.php
new file mode 100755
index 000000000..a643672d0
--- /dev/null
+++ b/application/libraries/barcodegen/class/BCGupcext5.barcode.php
@@ -0,0 +1,200 @@
+ 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)
+ *
+ *--------------------------------------------------------------------
+ * Copyright (C) Jean-Sebastien Goupil
+ * http://www.barcodephp.com
+ */
+include_once('BCGParseException.php');
+include_once('BCGBarcode1D.php');
+include_once('BCGLabel.php');
+
+class BCGupcext5 extends BCGBarcode1D {
+ protected $codeParity = array();
+
+ /**
+ * Constructor.
+ */
+ public function __construct() {
+ parent::__construct();
+
+ $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 */
+ );
+ }
+
+ /**
+ * Draws the barcode.
+ *
+ * @param resource $im
+ */
+ public function draw($im) {
+ // Checksum
+ $this->calculateChecksum();
+
+ // Starting Code
+ $this->drawChar($im, '001', true);
+
+ // Code
+ for ($i = 0; $i < 5; $i++) {
+ $this->drawChar($im, self::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, 0, 0, $this->positionX, $this->thickness);
+ }
+
+ /**
+ * Returns the maximal size of a barcode.
+ *
+ * @param int $w
+ * @param int $h
+ * @return int[]
+ */
+ public function getDimension($w, $h) {
+ $startlength = 4;
+ $textlength = 5 * 7;
+ $intercharlength = 2 * 4;
+
+ $w += $startlength + $textlength + $intercharlength;
+ $h += $this->thickness;
+ return parent::getDimension($w, $h);
+ }
+
+ /**
+ * Adds the default label.
+ */
+ protected function addDefaultLabel() {
+ parent::addDefaultLabel();
+
+ if ($this->defaultLabel !== null) {
+ $this->defaultLabel->setPosition(BCGLabel::POSITION_TOP);
+ }
+ }
+
+ /**
+ * Validates the input.
+ */
+ protected function validate() {
+ $c = strlen($this->text);
+ if ($c === 0) {
+ throw new BCGParseException('upcext5', 'No data has been entered.');
+ }
+
+ // Checking if all chars are allowed
+ for ($i = 0; $i < $c; $i++) {
+ if (array_search($this->text[$i], $this->keys) === false) {
+ throw new BCGParseException('upcext5', 'The character \'' . $this->text[$i] . '\' is not allowed.');
+ }
+ }
+
+ // Must contain 5 digits
+ if ($c !== 5) {
+ throw new BCGParseException('upcext5', 'Must contain 5 digits.');
+ }
+
+ parent::validate();
+ }
+
+ /**
+ * Overloaded method to calculate checksum.
+ */
+ protected 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.
+ */
+ protected function processChecksum() {
+ if ($this->checksumValue === false) { // Calculate the checksum only once
+ $this->calculateChecksum();
+ }
+
+ if ($this->checksumValue !== false) {
+ return $this->keys[$this->checksumValue];
+ }
+
+ return false;
+ }
+
+ /**
+ * Inverses the string when the $inverse parameter is equal to 1.
+ *
+ * @param string $text
+ * @param int $inverse
+ * @return string
+ */
+ private static function inverse($text, $inverse = 1) {
+ if ($inverse === 1) {
+ $text = strrev($text);
+ }
+
+ return $text;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/JoinDraw.php b/application/libraries/barcodegen/class/JoinDraw.php
new file mode 100755
index 000000000..79913a8ef
--- /dev/null
+++ b/application/libraries/barcodegen/class/JoinDraw.php
@@ -0,0 +1,194 @@
+image1 = $image1->get_im();
+ } else {
+ $this->image1 = $image1;
+ }
+ if ($image2 instanceof BCGDrawing) {
+ $this->image2 = $image2->get_im();
+ } else {
+ $this->image2 = $image2;
+ }
+
+ $this->background = $background;
+ $this->space = (int)$space;
+ $this->position = (int)$position;
+ $this->alignment = (int)$alignment;
+
+ $this->createIm();
+ }
+
+ /**
+ * Destroys the image.
+ */
+ public function __destruct() {
+ imagedestroy($this->im);
+ }
+
+ /**
+ * Finds the position where the barcode should be aligned.
+ *
+ * @param int $size1
+ * @param int $size2
+ * @param int $ailgnment
+ * @return int
+ */
+ private function findPosition($size1, $size2, $alignment) {
+ $rsize1 = max($size1, $size2);
+ $rsize2 = min($size1, $size2);
+
+ if ($alignment === self::ALIGN_LEFT) { // Or TOP
+ return 0;
+ } elseif ($alignment === self::ALIGN_CENTER) {
+ return $rsize1 / 2 - $rsize2 / 2;
+ } else { // RIGHT or TOP
+ return $rsize1 - $rsize2;
+ }
+ }
+
+ /**
+ * Change the alignments.
+ *
+ * @param int $alignment
+ * @return int
+ */
+ private function changeAlignment($alignment) {
+ if ($alignment === 0) {
+ return 1;
+ } elseif ($alignment === 1) {
+ return 0;
+ } else {
+ return 2;
+ }
+ }
+
+ /**
+ * Creates the image.
+ */
+ private function createIm() {
+ $w1 = imagesx($this->image1);
+ $w2 = imagesx($this->image2);
+ $h1 = imagesy($this->image1);
+ $h2 = imagesy($this->image2);
+
+ if ($this->position === self::POSITION_LEFT || $this->position === self::POSITION_RIGHT) {
+ $w = $w1 + $w2 + $this->space;
+ $h = max($h1, $h2);
+ } else {
+ $w = max($w1, $w2);
+ $h = $h1 + $h2 + $this->space;
+ }
+
+ $this->im = imagecreatetruecolor($w, $h);
+ imagefill($this->im, 0, 0, $this->background->allocate($this->im));
+
+ // We start defining position of images
+ if ($this->position === self::POSITION_TOP) {
+ if ($w1 > $w2) {
+ $posX1 = 0;
+ $posX2 = $this->findPosition($w1, $w2, $this->alignment);
+ } else {
+ $a = $this->changeAlignment($this->alignment);
+ $posX1 = $this->findPosition($w1, $w2, $a);
+ $posX2 = 0;
+ }
+
+ $posY2 = 0;
+ $posY1 = $h2 + $this->space;
+ } elseif ($this->position === self::POSITION_LEFT) {
+ if ($w1 > $w2) {
+ $posY1 = 0;
+ $posY2 = $this->findPosition($h1, $h2, $this->alignment);
+ } else {
+ $a = $this->changeAlignment($this->alignment);
+ $posY2 = 0;
+ $posY1 = $this->findPosition($h1, $h2, $a);
+ }
+
+ $posX2 = 0;
+ $posX1 = $w2 + $this->space;
+ } elseif ($this->position === self::POSITION_BOTTOM) {
+ if ($w1 > $w2) {
+ $posX2 = $this->findPosition($w1, $w2, $this->alignment);
+ $posX1 = 0;
+ } else {
+ $a = $this->changeAlignment($this->alignment);
+ $posX2 = 0;
+ $posX1 = $this->findPosition($w1, $w2, $a);
+ }
+
+ $posY1 = 0;
+ $posY2 = $h1 + $this->space;
+ } else { // defaults to RIGHT
+ if ($w1 > $w2) {
+ $posY2 = $this->findPosition($h1, $h2, $this->alignment);
+ $posY1 = 0;
+ } else {
+ $a = $this->changeAlignment($this->alignment);
+ $posY2 = 0;
+ $posY1 = $this->findPosition($h1, $h2, $a);
+ }
+
+ $posX1 = 0;
+ $posX2 = $w1 + $this->space;
+ }
+
+ imagecopy($this->im, $this->image1, $posX1, $posY1, 0, 0, $w1, $h1);
+ imagecopy($this->im, $this->image2, $posX2, $posY2, 0, 0, $w2, $h2);
+ }
+
+ /**
+ * Returns the new $im created.
+ *
+ * @return resource
+ */
+ public function get_im() {
+ return $this->im;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/drawer/BCGDraw.php b/application/libraries/barcodegen/class/drawer/BCGDraw.php
new file mode 100755
index 000000000..0eab27dd8
--- /dev/null
+++ b/application/libraries/barcodegen/class/drawer/BCGDraw.php
@@ -0,0 +1,38 @@
+im = $im;
+ }
+
+ /**
+ * Sets the filename.
+ *
+ * @param string $filename
+ */
+ public function setFilename($filename) {
+ $this->filename = $filename;
+ }
+
+ /**
+ * Method needed to draw the image based on its specification (JPG, GIF, etc.).
+ */
+ abstract public function draw();
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/drawer/BCGDrawJPG.php b/application/libraries/barcodegen/class/drawer/BCGDrawJPG.php
new file mode 100755
index 000000000..72bdd74de
--- /dev/null
+++ b/application/libraries/barcodegen/class/drawer/BCGDrawJPG.php
@@ -0,0 +1,102 @@
+dpi = max(1, $dpi);
+ } else {
+ $this->dpi = null;
+ }
+ }
+
+ /**
+ * Sets the quality of the JPG.
+ *
+ * @param int $quality
+ */
+ public function setQuality($quality) {
+ $this->quality = $quality;
+ }
+
+ /**
+ * Draws the JPG on the screen or in a file.
+ */
+ public 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);
+ }
+ }
+
+ private function setInternalProperties(&$bin) {
+ $this->internalSetDPI($bin);
+ $this->internalSetC($bin);
+ }
+
+ private function internalSetDPI(&$bin) {
+ if ($this->dpi !== null) {
+ $bin = substr_replace($bin, pack("Cnn", 0x01, $this->dpi, $this->dpi), 13, 5);
+ }
+ }
+
+ private function internalSetC(&$bin) {
+ 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;
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/class/drawer/BCGDrawPNG.php b/application/libraries/barcodegen/class/drawer/BCGDrawPNG.php
new file mode 100755
index 000000000..cd3164f7a
--- /dev/null
+++ b/application/libraries/barcodegen/class/drawer/BCGDrawPNG.php
@@ -0,0 +1,202 @@
+dpi = max(1, $dpi);
+ } else {
+ $this->dpi = null;
+ }
+ }
+
+ /**
+ * Draws the PNG on the screen or in a file.
+ */
+ public 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);
+ }
+ }
+
+ private function setInternalProperties(&$bin) {
+ // 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);
+ }
+ }
+
+ private function detectChunks($bin) {
+ $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;
+ }
+
+ private function internalSetDPI(&$bin, &$chunks) {
+ 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 = self::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 && $chunks[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);
+ }
+ }
+ }
+
+ private function internalSetC(&$bin, &$chunks) {
+ if (count($chunks) >= 2 && $chunks[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.
+ }
+
+ private static $crc_table = array();
+ private static $crc_table_computed = false;
+
+ private static function make_crc_table() {
+ for ($n = 0; $n < 256; $n++) {
+ $c = $n;
+ for ($k = 0; $k < 8; $k++) {
+ if (($c & 1) == 1) {
+ $c = 0xedb88320 ^ (self::SHR($c, 1));
+ } else {
+ $c = self::SHR($c, 1);
+ }
+ }
+ self::$crc_table[$n] = $c;
+ }
+
+ self::$crc_table_computed = true;
+ }
+
+ private static function SHR($x, $n) {
+ $mask = 0x40000000;
+
+ if ($x < 0) {
+ $x &= 0x7FFFFFFF;
+ $mask = $mask >> ($n - 1);
+ return ($x >> $n) | $mask;
+ }
+
+ return (int)$x >> (int)$n;
+ }
+
+ private static function update_crc($crc, $buf, $len) {
+ $c = $crc;
+
+ if (!self::$crc_table_computed) {
+ self::make_crc_table();
+ }
+
+ for ($n = 0; $n < $len; $n++) {
+ $c = self::$crc_table[($c ^ ord($buf[$n])) & 0xff] ^ (self::SHR($c, 8));
+ }
+
+ return $c;
+ }
+
+ private static function crc($data, $len) {
+ return self::update_crc(-1, $data, $len) ^ -1;
+ }
+}
+?>
diff --git a/application/libraries/barcodegen/font/Arial.ttf b/application/libraries/barcodegen/font/Arial.ttf
new file mode 100755
index 000000000..886789b85
Binary files /dev/null and b/application/libraries/barcodegen/font/Arial.ttf differ
diff --git a/application/libraries/barcodegen/html/BCGcodabar.php b/application/libraries/barcodegen/html/BCGcodabar.php
new file mode 100755
index 000000000..89feb0e03
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGcodabar.php
@@ -0,0 +1,28 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Known also as Ames Code, NW-7, Monarch, 2 of 7, Rationalized Codabar.
+
Codabar was developed in 1972 by Pitney Bowes, Inc.
+
This symbology is useful to encode digital information. It is a self-checking code, there is no check digit.
+
Codabar is used by blood bank, photo labs, library, FedEx...
+
Coding can be with an unspecified length composed by numbers, plus and minus sign, colon, slash, dot, dollar.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGcode11.php b/application/libraries/barcodegen/html/BCGcode11.php
new file mode 100755
index 000000000..f7bccd8e2
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGcode11.php
@@ -0,0 +1,28 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Known also as USD-8.
+
Code 11 was developed in 1977 as a high-density numeric symbology.
+
Used to identify telecommunications equipment.
+
Code 11 is a numeric symbology and its character set consists of 10 digital characters and the dash symbol (-).
+
There is a "C" check digit. If the length of encoded message is greater thant 10, a "K" check digit may be used.
Code 128 is a high-density alphanumeric symbology.
+
Used extensively worldwide.
+
Code 128 is designed to encode 128 full ASCII characters.
+
The symbology includes a checksum digit.
+
Code 128A handles capital letters Code 128B handles capital letters and lowercase Code 128C handles group of 2 numbers
+
Your browser may not be able to write the special characters (NUL, SOH, etc.) but you can write them with the code.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGcode39.php b/application/libraries/barcodegen/html/BCGcode39.php
new file mode 100755
index 000000000..7cd0c96a2
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGcode39.php
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+ 1)); ?>
+
+
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Known also as USS Code 39, 3 of 9.
+
Code 39 can encode alphanumeric characters.
+
The symbology is used in non-retail environment.
+
Code 39 is designed to encode 26 upper case letters, 10 digits and 7 special characters.
Code 93 was designed to provide a higher density and data security enhancement to Code 39.
+
Used primarily by Canadian postal office to encode supplementary delivery information.
+
Similar to Code 39, Code 93 has the same 43 characters plus 5 special ones to encode the ASCII 0 to 127.
+
This symbology composed of 2 check digits ("C" and "K").
+
Your browser may not be able to write the special characters (NUL, SOH, etc.) but you can write them with the code.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGean13.php b/application/libraries/barcodegen/html/BCGean13.php
new file mode 100755
index 000000000..761bbf04e
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGean13.php
@@ -0,0 +1,27 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
EAN means Internal Article Numbering.
+
It is an extension of UPC-A to include the country information.
+
Used with consumer products internationally.
+
Composed by 2 number system, 5 manufacturer code, 5 product code and 1 check digit.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGean8.php b/application/libraries/barcodegen/html/BCGean8.php
new file mode 100755
index 000000000..b1ad3471e
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGean8.php
@@ -0,0 +1,26 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
EAN-8 is a short version of EAN-13.
+
Composed by 7 digits and 1 check digit.
+
There is no conversion available between EAN-8 and EAN-13.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGgs1128.php b/application/libraries/barcodegen/html/BCGgs1128.php
new file mode 100755
index 000000000..2dc9dda25
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGgs1128.php
@@ -0,0 +1,250 @@
+ 'Select an identifier',
+ '00' => 'Serial Shipping Container Code (SSCC-18)',
+ '01' => 'Shipping Container Code (SSC)',
+ '02' => 'Number of containers',
+ '10' => 'Batch Number',
+ '11' => 'Production Date',
+ '12' => 'Due date',
+ '13' => 'Packaging Date',
+ '15' => 'Sell by Date (Quality Control)',
+ '17' => 'Expiration Date',
+ '20' => 'Product Variant',
+ '21' => 'Serial Number',
+ '240' => 'Additional Product Identification',
+ '241' => 'Customer part number',
+ '250' => 'Second Serial Number',
+ '251' => 'Reference to source entity',
+ '253' => 'Global Document Type Identifier',
+ '30' => 'Quantity Each',
+ '310y' => 'Product Net Weight in kg',
+ '311y' => 'Product Length/1st Dimension, in meters',
+ '312y' => 'Product Width/Diameter/2nd Dimension, in meters',
+ '313y' => 'Product Depth/Thickness/3rd Dimension, in meters',
+ '314y' => 'Product Area, in square meters',
+ '315y' => 'Product Volume, in liters',
+ '316y' => 'product Volume, in cubic meters',
+ '320y' => 'Product Net Weight, in pounds',
+ '321y' => 'Product Length/1st Dimension, in inches',
+ '322y' => 'Product Length/1st Dimension, in feet',
+ '323y' => 'Product Length/1st Dimension, in yards',
+ '324y' => 'Product Width/Diameter/2nd Dimension, in inches',
+ '325y' => 'Product Width/Diameter/2nd Dimension, in feet',
+ '326y' => 'Product Width/Diameter/2nd Dimension, in yards',
+ '327y' => 'Product Depth/Thickness/3rd Dimension, in inches',
+ '328y' => 'Product Depth/Thickness/3rd Dimension, in feet',
+ '329y' => 'Product Depth/Thickness/3rd Dimension, in yards',
+ '330y' => 'Container Gross Weight (Kg)',
+ '331y' => 'Container Length/1st Dimension (Meters)',
+ '332y' => 'Container Width/Diameter/2nd Dimension (Meters)',
+ '333y' => 'Container Depth/Thickness/3rd Dimension (Meters)',
+ '334y' => 'Container Area (Square Meters)',
+ '335y' => 'Container Gross Volume (Liters)',
+ '336y' => 'Container Gross Volume (Cubic Meters)',
+ '337y' => 'Kilograms per square meter',
+ '340y' => 'Container Gross Weight (Pounds)',
+ '341y' => 'Container Length/1st Dimension, in inches',
+ '342y' => 'Container Length/1st Dimension, in feet',
+ '343y' => 'Container Length/1st Dimension in, in yards',
+ '344y' => 'Container Width/Diameter/2nd Dimension, in inches',
+ '345y' => 'Container Width/Diameter/2nd Dimension, in feet',
+ '346y' => 'Container Width/Diameter/2nd Dimension, in yards',
+ '347y' => 'Container Depth/Thickness/Height/3rd Dimension, in inches',
+ '348y' => 'Container Depth/Thickness/Height/3rd Dimension, in feet',
+ '349y' => 'Container Depth/Thickness/Height/3rd Dimension, in yards',
+ '350y' => 'Product Area (Square Inches)',
+ '351y' => 'Product Area (Square Feet)',
+ '352y' => 'Product Area (Square Yards)',
+ '353y' => 'Container Area (Square Inches)',
+ '354y' => 'Container Area (Square Feet)',
+ '355y' => 'Container Area (Square Yards)',
+ '356y' => 'Net Weight (Troy Ounces)',
+ '357y' => 'Kilograms per square meter',
+ '360y' => 'Product Volume (Quarts)',
+ '361y' => 'Product Volume (Gallons)',
+ '362y' => 'Container Gross Volume (Quarts)',
+ '363y' => 'Container Gross Volume (Gallons)',
+ '364y' => 'Product Volume (Cubic Inches)',
+ '365y' => 'Product Volume (Cubic Feet)',
+ '366y' => 'Product Volume (Cubic Yards)',
+ '367y' => 'Container Gross Volume (Cubic Inches)',
+ '368y' => 'Container Gross Volume (Cubic Feet)',
+ '369y' => 'Container Gross Volume (Cubic Yards)',
+ '37' => 'Number of Units Contained',
+ '390y' => 'Amount payable-single monetary area',
+ '391y' => 'Amount payable with ISO currency code',
+ '392y' => 'Amount payable for a Variable Measure Trade Item single monetary unit',
+ '393y' => 'Amount payable for a Variable Measure Trade Item - with ISO currency code',
+ '400' => 'Customer Purchase Order Number',
+ '401' => 'Consignment number',
+ '402' => 'Shipment Identification Number',
+ '403' => 'Routing code',
+ '410' => 'Ship To/Deliver To Location Code (EAN13 or DUNS code)',
+ '411' => 'Bill To/Invoice Location Code (EAN13 or DUNS code)',
+ '412' => 'Purchase From Location Code (EAN13 or DUNS code)',
+ '413' => 'Ship for - deliver for - forward to EAN.UCC Global Location Number',
+ '414' => 'Identification of a physical location EAN.UCC Global Location Number',
+ '415' => 'EAN.UCC Global Location Number of the invoicing party',
+ '420' => 'Ship To/Deliver To Postal Code (Single Postal Authority)',
+ '421' => 'Ship To/Deliver To Postal Code (Multiple Postal Authority)',
+ '422' => 'Country of origin of a trade item',
+ '8001' => 'Roll Products - Width/Length/Core Diameter',
+ '8002' => 'Electronic Serial Number (ESN) for Cellular Phone',
+ '8003' => 'UPC/EAN Number and Serial Number of Returnable Asset',
+ '8004' => 'UPC/EAN Serial Identification',
+ '8005' => 'Price per Unit of Measure',
+ '8006' => 'Identification of the component of a trade item',
+ '8007' => 'International Bank Account Number',
+ '8018' => 'EAN.UCC Global Service Relation Number',
+ '8020' => 'Payment Slip Reference Number',
+ '8100' => 'Coupon Extended Code: Number System and Offer',
+ '8101' => '8101 Coupon Extended Code: Number System, Offer, End of Offer',
+ '8102' => 'Coupon Extended Code: Number System preceded by 0',
+ '90' => 'Mutually Agreed Between Trading Partners',
+ '91' => 'Internal Company Codes',
+ '92' => 'Internal Company Codes',
+ '93' => 'Internal Company Codes',
+ '94' => 'Internal Company Codes',
+ '95' => 'Internal Company Codes',
+ '96' => 'Internal Company Codes',
+ '97' => 'Internal Company Codes',
+ '98' => 'Internal Company Codes',
+ '99' => 'Internal Company Codes'
+);
+
+foreach ($identifiers as $key => $value) {
+ if ($key) {
+ $identifiers[$key] = $key . ' - ' . $value;
+ }
+}
+
+registerImageKey('code', 'BCGgs1128');
+
+$vals = array();
+for($i = 0; $i <= 127; $i++) {
+ $vals[] = '%' . sprintf('%02X', $i);
+}
+$characters = array(
+ 'NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL', 'BS', 'TAB', 'LF', 'VT', 'FF', 'CR', 'SO', 'SI', 'DLE', 'DC1', 'DC2', 'DC3', 'DC4', 'NAK', 'SYN', 'ETB', 'CAN', 'EM', 'SUB', 'ESC', 'FS', 'GS', 'RS', 'US',
+ ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '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', '[', '\\', ']', '^', '_',
+ '`', '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', '{', '|', '}', '~', 'DEL'
+);
+?>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGi25.php b/application/libraries/barcodegen/html/BCGi25.php
new file mode 100755
index 000000000..7b5fbe66c
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGi25.php
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+ 1)); ?>
+
+
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Interleaved 2 of 5 is based on Standard 2 of 5 symbology.
+
There is an optional checksum.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGintelligentmail.php b/application/libraries/barcodegen/html/BCGintelligentmail.php
new file mode 100755
index 000000000..94bba9f87
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGintelligentmail.php
@@ -0,0 +1,99 @@
+
+
+
+ You can provide
+ 5 digits (ZIP Code)
+ 9 digits (ZIP+4 code)
+ 11 digits (ZIP+4 code+2 digits)
+
+
Contains a barcode identifier, service type identifier, mailer id and serial number.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGisbn.php b/application/libraries/barcodegen/html/BCGisbn.php
new file mode 100755
index 000000000..2f6581218
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGisbn.php
@@ -0,0 +1,27 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
ISBN stands for International Standard Book Number.
+
ISBN type is based on EAN-13.
+
Previously, all ISBN were in EAN-10 format. EAN-13 uses the same encoding but may contain different data in the ISBN number.
+
Composed by a GS1 prefix (for ISBN-13), a group identifier, a publisher code, an item number and a check digit.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGmsi.php b/application/libraries/barcodegen/html/BCGmsi.php
new file mode 100755
index 000000000..6a09c9a1d
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGmsi.php
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+ 1)); ?>
+
+
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Developed by the MSI Data Corporation.
+
Used primarily to mark retail shelves for inventory control.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGothercode.php b/application/libraries/barcodegen/html/BCGothercode.php
new file mode 100755
index 000000000..3d72c026a
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGothercode.php
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Enter width of each bars with one characters. Begin by a bar.
+
10523: Will do 2px bar, 1px space, 6px bar, 3px space, 4px bar.
+ You can provide
+ 5 digits (ZIP Code)
+ 9 digits (ZIP+4 code)
+ 11 digits (ZIP+4 code+2 digits)
+ (Those 2 digits are taken from your address. If your address is 6453, the code will be 53.)
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGs25.php b/application/libraries/barcodegen/html/BCGs25.php
new file mode 100755
index 000000000..441c3bfaa
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGs25.php
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+ 1)); ?>
+
+
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Known also as Industrial 2 of 5.
+
Standard 2 of 5 is a low-density numeric symbology that has been with us since the 1960s.
+
There is an optional checksum.
+
Note: Standard 2 of 5 is really tough to read!
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGupca.php b/application/libraries/barcodegen/html/BCGupca.php
new file mode 100755
index 000000000..2bcee8a39
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGupca.php
@@ -0,0 +1,36 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Encoded as EAN-13.
+
Most common and well-known in the USA.
+
There is 1 number system (NS), 5 manufacturer code, 5 product code and 1 check digit.
+
+ NS Description :
+ 0 = Regular UPC Code
+ 2 = Weight Items
+ 3 = Drug/Health Items
+ 4 = In-Store Use on Non-Food Items
+ 5 = Coupons
+ 7 = Regular UPC Code
+ And other are Reserved.
+
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGupce.php b/application/libraries/barcodegen/html/BCGupce.php
new file mode 100755
index 000000000..73a4d8f37
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGupce.php
@@ -0,0 +1,27 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Short version of UPC symbol, 8 characters.
+
It is a conversion of an UPC-A for small package.
+
You can provide directly an UPC-A (11 chars) or UPC-E (6 chars) code.
+
UPC-E contain a system number and a check digit.
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGupcext2.php b/application/libraries/barcodegen/html/BCGupcext2.php
new file mode 100755
index 000000000..1288d70be
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGupcext2.php
@@ -0,0 +1,25 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Extension for UPC-A, UPC-E, EAN-13 and EAN-8.
+
Used for encode additional information for newspaper, books...
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/BCGupcext5.php b/application/libraries/barcodegen/html/BCGupcext5.php
new file mode 100755
index 000000000..cd911c4da
--- /dev/null
+++ b/application/libraries/barcodegen/html/BCGupcext5.php
@@ -0,0 +1,33 @@
+
+
+
+
Valid Characters
+
+
+
+
+
Explanation
+
+
Extension for UPC-A, UPC-E, EAN-13 and EAN-8.
+
Used to encode suggested retail price.
+
If the first number is a 0, the price xx.xx is expressed in British Pounds. If it is a 5, it is expressed in US dollars.
+
+ Special Code Description:
+ 90000: No suggested retail price
+ 99991: The item is a complementary of another one. Normally free
+ 99990: Used bh National Association of College Stores to mark "used book"
+ 90001 to 98999: Internal purposes for some publishers
+
+
+
+
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/barcode.js b/application/libraries/barcodegen/html/barcode.js
new file mode 100755
index 000000000..016638670
--- /dev/null
+++ b/application/libraries/barcodegen/html/barcode.js
@@ -0,0 +1,120 @@
+$(function() {
+ var attachMainBehaviors = function() {
+ $("select[name=type]").on("change", function() {
+ var selected = $(this).find("option:selected");
+ window.location.href = selected.val();
+ });
+
+ $("select[name=filetype]").on("change", function() {
+ var selected = $(this).find("option:selected"),
+ val = selected.val(),
+ dpi = $("input[name=dpi]"),
+ dpiUnavailable = $("#dpiUnavailable");
+
+ if (val === "PNG" || val === "JPEG") {
+ dpi.prop("disabled", false);
+ dpiUnavailable.hide();
+ } else {
+ dpi.prop("disabled", true);
+ dpiUnavailable.show();
+ }
+ }).change();
+
+ var text = $("input[name=text]");
+
+ $("#validCharacters").on("click", "[data-output]", function() {
+ var $this = $(this),
+ escaped = $this.data("escaped"),
+ value = $this.data("output");
+ if (escaped) {
+ value = unescape(value);
+ }
+
+ text
+ .val(text.val() + value)
+ .focus();
+ });
+ }, attachUIBehaviors = function() {
+ $("table").each(function() {
+ var $this = $(this);
+ $this.find("tr:even").addClass("even");
+ $this.find("tr:odd").addClass("odd");
+ });
+ }, attachSpecificBehaviors = function() {
+ $("#specificOptions li").each(function() {
+ var $this = $(this),
+ code = $("
");
+ code.find(".title").append($this.find(".title"));
+ code.find(".value").append($this.find(".value"));
+
+ $("div.configurations tr:last").before(code);
+ });
+ }, attachInfoBehaviors = function() {
+ var showTooltip = function(object) {
+ object
+ .on("mouseover", function() {
+ var timer = $(this).data("timer");
+ if (timer) {
+ clearTimeout(timer);
+ }
+ })
+ .on("mouseout", function() {
+ var that = $(this);
+ that.data("timer", setTimeout(function() {
+ that.removeClass("visible");
+ }, 1000));
+ });
+
+ return function() {
+ var $this = $(this),
+ offset = $this.offset(),
+ timer = object.data("timer");
+
+ if (timer) {
+ clearTimeout(timer);
+ }
+
+ // Show it once so we can get the outerWidth properly
+ object
+ .css({
+ left: -99999,
+ top: -99999
+ })
+ .addClass("visible")
+ .css({
+ left: offset.left + $this.width() - object.outerWidth(),
+ top: offset.top + $this.height()
+ });
+ return false;
+ };
+ },
+ hideTooltip = function(object) {
+ return function() {
+ object.data("timer", setTimeout(function() {
+ object.removeClass("visible");
+ }, 1000));
+ };
+ },
+ bubbleize = function(object) {
+ return object
+ .addClass("bubble")
+ .attr("role", "tooltip")
+ .appendTo(document.body);
+ },
+ explanation = bubbleize($("#explanation")),
+ validCharacters = bubbleize($("#validCharacters"));
+
+ $(".info.explanation")
+ .on("mouseover focusin", showTooltip(explanation))
+ .on("mouseout focusout", hideTooltip(explanation));
+
+ $(".info.characters")
+ .on("mouseover focusin", showTooltip(validCharacters))
+ .on("mouseout focusout", hideTooltip(validCharacters));
+ };
+
+ attachSpecificBehaviors();
+ attachMainBehaviors();
+ attachUIBehaviors();
+ attachInfoBehaviors();
+});
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGBarcode1D.php b/application/libraries/barcodegen/html/config/BCGBarcode1D.php
new file mode 100755
index 000000000..ca56f3589
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGBarcode1D.php
@@ -0,0 +1,16 @@
+setThickness(max(9, min(90, intval($get['thickness']))));
+ }
+
+ $font = 0;
+ if ($get['font_family'] !== '0' && intval($get['font_size']) >= 1) {
+ $font = new BCGFontFile($font_dir . '/' . $get['font_family'], intval($get['font_size']));
+ }
+
+ $barcode->setFont($font);
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGcodabar.php b/application/libraries/barcodegen/html/config/BCGcodabar.php
new file mode 100755
index 000000000..a3a574cf7
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGcodabar.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGcode11.php b/application/libraries/barcodegen/html/config/BCGcode11.php
new file mode 100755
index 000000000..0bd083ae4
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGcode11.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGcode128.php b/application/libraries/barcodegen/html/config/BCGcode128.php
new file mode 100755
index 000000000..521e000bb
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGcode128.php
@@ -0,0 +1,12 @@
+setStart($get['start'] === 'NULL' ? null : $get['start']);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGcode39.php b/application/libraries/barcodegen/html/config/BCGcode39.php
new file mode 100755
index 000000000..ce6cfd5df
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGcode39.php
@@ -0,0 +1,12 @@
+setChecksum($get['checksum'] === '1' ? true : false);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGcode39extended.php b/application/libraries/barcodegen/html/config/BCGcode39extended.php
new file mode 100755
index 000000000..ab8185475
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGcode39extended.php
@@ -0,0 +1,12 @@
+setChecksum($get['checksum'] === '1' ? true : false);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGcode93.php b/application/libraries/barcodegen/html/config/BCGcode93.php
new file mode 100755
index 000000000..2f58b460d
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGcode93.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGean13.php b/application/libraries/barcodegen/html/config/BCGean13.php
new file mode 100755
index 000000000..8f10a68f4
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGean13.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGean8.php b/application/libraries/barcodegen/html/config/BCGean8.php
new file mode 100755
index 000000000..4072741c2
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGean8.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGgs1128.php b/application/libraries/barcodegen/html/config/BCGgs1128.php
new file mode 100755
index 000000000..e4c6b66fe
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGgs1128.php
@@ -0,0 +1,12 @@
+setStart($get['start'] === 'NULL' ? null : $get['start']);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGi25.php b/application/libraries/barcodegen/html/config/BCGi25.php
new file mode 100755
index 000000000..cb5003b30
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGi25.php
@@ -0,0 +1,12 @@
+setChecksum($get['checksum'] === '1' ? true : false);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGintelligentmail.php b/application/libraries/barcodegen/html/config/BCGintelligentmail.php
new file mode 100755
index 000000000..eb1bbebcd
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGintelligentmail.php
@@ -0,0 +1,12 @@
+setTrackingCode(intval($get['barcodeIdentifier']), intval($get['serviceType']), intval($get['mailerIdentifier']), intval($get['serialNumber']));
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGisbn.php b/application/libraries/barcodegen/html/config/BCGisbn.php
new file mode 100755
index 000000000..57e5ddc87
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGisbn.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGmsi.php b/application/libraries/barcodegen/html/config/BCGmsi.php
new file mode 100755
index 000000000..74c30c35a
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGmsi.php
@@ -0,0 +1,12 @@
+setChecksum($get['checksum'] === '1' ? true : false);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGothercode.php b/application/libraries/barcodegen/html/config/BCGothercode.php
new file mode 100755
index 000000000..1acc70969
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGothercode.php
@@ -0,0 +1,12 @@
+setLabel($get['label']);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGpostnet.php b/application/libraries/barcodegen/html/config/BCGpostnet.php
new file mode 100755
index 000000000..142843dff
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGpostnet.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGs25.php b/application/libraries/barcodegen/html/config/BCGs25.php
new file mode 100755
index 000000000..5266cecab
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGs25.php
@@ -0,0 +1,12 @@
+setChecksum($get['checksum'] === '1' ? true : false);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGupca.php b/application/libraries/barcodegen/html/config/BCGupca.php
new file mode 100755
index 000000000..b4e5e2b70
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGupca.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGupce.php b/application/libraries/barcodegen/html/config/BCGupce.php
new file mode 100755
index 000000000..294a9ecd3
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGupce.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGupcext2.php b/application/libraries/barcodegen/html/config/BCGupcext2.php
new file mode 100755
index 000000000..158a20292
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGupcext2.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/config/BCGupcext5.php b/application/libraries/barcodegen/html/config/BCGupcext5.php
new file mode 100755
index 000000000..f518ebc13
--- /dev/null
+++ b/application/libraries/barcodegen/html/config/BCGupcext5.php
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/delete.png b/application/libraries/barcodegen/html/delete.png
new file mode 100755
index 000000000..fb0c022de
Binary files /dev/null and b/application/libraries/barcodegen/html/delete.png differ
diff --git a/application/libraries/barcodegen/html/error.png b/application/libraries/barcodegen/html/error.png
new file mode 100755
index 000000000..ceab5af8c
Binary files /dev/null and b/application/libraries/barcodegen/html/error.png differ
diff --git a/application/libraries/barcodegen/html/favicon.ico b/application/libraries/barcodegen/html/favicon.ico
new file mode 100755
index 000000000..939bd60ac
Binary files /dev/null and b/application/libraries/barcodegen/html/favicon.ico differ
diff --git a/application/libraries/barcodegen/html/image.php b/application/libraries/barcodegen/html/image.php
new file mode 100755
index 000000000..9f8dc7c3f
--- /dev/null
+++ b/application/libraries/barcodegen/html/image.php
@@ -0,0 +1,97 @@
+ BCGDrawing::IMG_FORMAT_PNG, 'JPEG' => BCGDrawing::IMG_FORMAT_JPEG, 'GIF' => BCGDrawing::IMG_FORMAT_GIF);
+
+$drawException = null;
+try {
+ $color_black = new BCGColor(0, 0, 0);
+ $color_white = new BCGColor(255, 255, 255);
+
+ $code_generated = new $className();
+
+ if (function_exists('baseCustomSetup')) {
+ baseCustomSetup($code_generated, $_GET);
+ }
+
+ if (function_exists('customSetup')) {
+ customSetup($code_generated, $_GET);
+ }
+
+ $code_generated->setScale(max(1, min(4, $_GET['scale'])));
+ $code_generated->setBackgroundColor($color_white);
+ $code_generated->setForegroundColor($color_black);
+
+ if ($_GET['text'] !== '') {
+ $text = convertText($_GET['text']);
+ $code_generated->parse($text);
+ }
+} catch(Exception $exception) {
+ $drawException = $exception;
+}
+
+$drawing = new BCGDrawing('', $color_white);
+if($drawException) {
+ $drawing->drawException($drawException);
+} else {
+ $drawing->setBarcode($code_generated);
+ $drawing->setRotationAngle($_GET['rotation']);
+ $drawing->setDPI($_GET['dpi'] === 'NULL' ? null : max(72, min(300, intval($_GET['dpi']))));
+ $drawing->draw();
+}
+
+switch ($_GET['filetype']) {
+ case 'PNG':
+ header('Content-Type: image/png');
+ break;
+ case 'JPEG':
+ header('Content-Type: image/jpeg');
+ break;
+ case 'GIF':
+ header('Content-Type: image/gif');
+ break;
+}
+
+$drawing->finish($filetypes[$_GET['filetype']]);
+?>
\ No newline at end of file
diff --git a/application/libraries/barcodegen/html/include/BCGBarcode1D.php b/application/libraries/barcodegen/html/include/BCGBarcode1D.php
new file mode 100755
index 000000000..dcb4ce9fd
--- /dev/null
+++ b/application/libraries/barcodegen/html/include/BCGBarcode1D.php
@@ -0,0 +1,11 @@
+
+