diff --git a/CMakeLists.txt b/CMakeLists.txt index acbb3aa..3afa1e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ find_package(ZLIB 1.2 REQUIRED) #======================================= # Subdirectories #======================================= +add_subdirectory (glbarcode) add_subdirectory (glabels) add_subdirectory (templates) add_subdirectory (translations) diff --git a/COPYING.README_FIRST b/COPYING.README_FIRST index b96c278..1f702e3 100644 --- a/COPYING.README_FIRST +++ b/COPYING.README_FIRST @@ -11,6 +11,14 @@ GLABELS: directory for details. +GLBARCODE: + + gLabels currently includes a version of the glbarcode++ library, located in + the "glbarcode/" subdirectory. It is licensed under the GNU LESSER GENERAL + PUBLIC LICENSE (LGPL); either version 3 of the License, or (at your option) + any later version -- see the 'COPYING-LIB + + DOCUMENTATION: The gLabels documentation, located in the "docs/" and "help/" subdirectories, diff --git a/glbarcode/Barcode.cpp b/glbarcode/Barcode.cpp new file mode 100644 index 0000000..ce52469 --- /dev/null +++ b/glbarcode/Barcode.cpp @@ -0,0 +1,195 @@ +/* Barcode.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "Barcode.h" + +#include + +#include "DrawingPrimitives.h" + + +namespace glbarcode +{ + + /* + * Barcode private data + */ + struct Barcode::PrivateData { + + bool mShowTextFlag; /**< Display text flag */ + bool mChecksumFlag; /**< Add checksum flag */ + + double mW; /**< Width of barcode (points) */ + double mH; /**< Height of barcode (points) */ + + bool mIsEmpty; /**< Empty data flag */ + bool mIsDataValid; /**< Valid data flag */ + + std::list mPrimitives; /**< List of drawing primitives */ + + }; + + + Barcode::Barcode() + { + d = new Barcode::PrivateData; + + d->mShowTextFlag = false; + d->mChecksumFlag = false; + + d->mW = 0; + d->mH = 0; + + d->mIsEmpty = true; + d->mIsDataValid = false; + } + + + Barcode::~Barcode() + { + clear(); /* Clear drawing primitives. */ + delete d; + } + + + Barcode& Barcode::setShowText( bool value ) + { + d->mShowTextFlag = value; + return *this; + } + + + bool Barcode::showText( void ) const + { + return d->mShowTextFlag; + } + + + Barcode& Barcode::setChecksum( bool value ) + { + d->mChecksumFlag = value; + return *this; + } + + + bool Barcode::checksum( void ) const + { + return d->mChecksumFlag; + } + + + void Barcode::render( Renderer& renderer ) + { + renderer.render( d->mW, d->mH, d->mPrimitives ); + } + + + bool Barcode::isEmpty( void ) const + { + return d->mIsEmpty; + } + + + void Barcode::setIsEmpty( bool value ) + { + d->mIsEmpty = value; + } + + + bool Barcode::isDataValid( void ) const + { + return d->mIsDataValid; + } + + + void Barcode::setIsDataValid( bool value ) + { + d->mIsDataValid = value; + } + + + double Barcode::width( void ) const + { + return d->mW; + } + + + double Barcode::height( void ) const + { + return d->mH; + } + + + void Barcode::setWidth( double w ) + { + d->mW = w; + } + + + void Barcode::setHeight( double h ) + { + d->mH = h; + } + + + void Barcode::clear( void ) + { + std::list::iterator primitive; + + for ( primitive = d->mPrimitives.begin(); primitive != d->mPrimitives.end(); primitive++ ) + { + delete *primitive; + } + + d->mPrimitives.clear(); + } + + + void Barcode::addLine( double x, double y, double w, double h ) + { + d->mPrimitives.push_back( new DrawingPrimitiveLine( x, y, w, h ) ); + } + + + void Barcode::addBox( double x, double y, double w, double h ) + { + d->mPrimitives.push_back( new DrawingPrimitiveBox( x, y, w, h ) ); + } + + + void Barcode::addText( double x, double y, double size, const std::string& text ) + { + d->mPrimitives.push_back( new DrawingPrimitiveText( x, y, size, text ) ); + } + + + void Barcode::addRing( double x, double y, double r, double w ) + { + d->mPrimitives.push_back( new DrawingPrimitiveRing( x, y, r, w ) ); + } + + + void Barcode::addHexagon( double x, double y, double h ) + { + d->mPrimitives.push_back( new DrawingPrimitiveHexagon( x, y, h ) ); + } + + +} diff --git a/glbarcode/Barcode.h b/glbarcode/Barcode.h new file mode 100644 index 0000000..8cae869 --- /dev/null +++ b/glbarcode/Barcode.h @@ -0,0 +1,316 @@ +/* Barcode.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_Barcode_h +#define glbarcode_Barcode_h + + +#include + +#include "Renderer.h" + + +/** + * Barcode base for CAPI + */ +extern "C" struct gbcBarcode {}; + + +namespace glbarcode +{ + + /** + * @class Barcode Barcode.h glbarcode/Barcode.h + * + * The Barcode class is the base class for all barcode implementations. This class + * provides the public interfaces and basic infrastructure for all barcode implementations. + * Implementations would not typically directly implement this class, but instead would implement + * either Barcode1dBase (for 1D symbologies) or Barcode2dBase (for 2D symbologies). + * + * See Barcode1dBase or Barcode2dBase. + * + */ + class Barcode : public gbcBarcode + { + + protected: + /** + * Default constructor. + */ + Barcode(); + + + public: + /** + * Destructor. + */ + virtual ~Barcode(); + + + /** + * Set accessor for "showText" property. + * + * @param[in] value Boolean value + * + * @returns A reference to this Barcode object for property chaining + * + * @sa showText() + */ + Barcode& setShowText( bool value ); + + + /** + * Get accessor for "showText" property. + * + * @returns Value of boolean "showText" property + * + * @sa setShowText() + */ + bool showText( void ) const; + + + /** + * Set accessor for "checksum" property. + * + * @param[in] value Boolean value + * + * @returns A reference to this Barcode object for property chaining + * + * @sa checksum() + */ + Barcode& setChecksum( bool value ); + + + /** + * Get accessor for "checksum" property. + * + * @returns Value of boolean "checksum" property + * + * @sa setChecksum() + */ + bool checksum( void ) const; + + + /** + * Build barcode from data. + * + * @param[in] data Data to encode in barcode + * @param[in] w Requested width of barcode (0 = auto size) + * @param[in] h Requested height of barcode (0 = auto size) + * + * @returns A reference to this Barcode object for chaining methods + */ + virtual Barcode& build( const std::string& data, + double w = 0, + double h = 0 ) = 0; + + + /** + * Render barcode using given Renderer object. + * + * @param[in] renderer A Renderer object + */ + void render( Renderer& renderer ); + + + /** + * Is barcode data empty? + * + * @return True if barcode data is empty + * @return False if barcode data is not empty + * + * @sa setIsEmpty() + */ + bool isEmpty( void ) const; + + + /** + * Is barcode data valid? + * + * @return True if barcode data is valid + * @return False if barcode data is not valid for implemented barcode type + * + * @sa setIsDataValid() + */ + bool isDataValid( void ) const; + + + /** + * Get actual width of barcode (may differ from requested width). + * + * @return Actual width of barcode (points) + * + * @sa setWidth() + */ + double width( void ) const; + + + /** + * Get actual height of barcode (may differ from requested height). + * + * @return Actual height of barcode (points) + * + * @sa setHeight() + */ + double height( void ) const; + + + protected: + /** + * Clear drawing primitives. + */ + void clear( void ); + + + /** + * Add line drawing primitive + * + * To be used by build() implementations during vectorization. + * + * @image html figure-primitive-line.svg "Line primitive properties" + * + * @param[in] x X coordinate of line's origin (points) + * @param[in] y Y coordinate of line's origin (points) + * @param[in] w Bar width (points) + * @param[in] h Bar height (points) + */ + void addLine( double x, double y, double w, double h ); + + + /** + * Add box drawing primitive + * + * To be used by build() implementations during vectorization. + * + * @image html figure-primitive-box.svg "Box primitive properties" + * + * @param[in] x X coordinate of box's origin (points) + * @param[in] y Y coordinate of box's origin (points) + * @param[in] w Width of box (points) + * @param[in] h Height of box (points) + */ + void addBox( double x, double y, double w, double h ); + + + /** + * Add text drawing primitive + * + * To be used by build() implementations during vectorization. + * + * @image html figure-primitive-text.svg "Text primitive properties" + * + * @param[in] x X coordinate of text's origin (points) + * @param[in] y Y coordinate of text's origin (points) + * @param[in] size Font size of text (points) + * @param[in] text Text + */ + void addText( double x, double y, double size, const std::string& text ); + + + /** + * Add ring drawing primitive + * + * To be used by build() implementations during vectorization. + * + * @image html figure-primitive-ring.svg "Ring primitive properties" + * + * @param[in] x X coordinate of ring's origin (points) + * @param[in] y Y coordinate of ring's origin (points) + * @param[in] r Radius of ring (points) + * @param[in] w Line width of ring (points) + */ + void addRing( double x, double y, double r, double w ); + + + /** + * Add hexagon drawing primitive + * + * To be used by build() implementations during vectorization. + * + * @image html figure-primitive-hexagon.svg "Hexagon primitive properties" + * + * @param[in] x X coordinate of hexagon's origin (points) + * @param[in] y Y coordinate of hexagon's origin (points) + * @param[in] h Height of hexagon (points) + */ + void addHexagon( double x, double y, double h ); + + + /** + * Set is empty property. + * + * To be used by build() implementations to indicate if input data is empty. + * + * @param[in] value Boolean value of flag + * + * @sa isEmpty() + */ + void setIsEmpty( bool value ); + + + /** + * Set is data valid property. + * + * To be used by build() implementations to indicate if input data is valid or not. + * + * @param[in] value Boolean value of flag + * + * @sa isDataValid() + */ + void setIsDataValid( bool value ); + + + /** + * Set new width of barcode. + * + * To be used by build() implementations to override requested width of barcode. + * + * @param[in] w Actual width of barcode (points) + * + * @sa width() + */ + void setWidth( double w ); + + + /** + * Set new height of barcode. + * + * To be used by build() implementations to override requested height of barcode. + * + * @param[in] h Actual height of barcode (points) + * + * @sa height() + */ + void setHeight( double h ); + + + private: + /** + * Barcode Private data + */ + struct PrivateData; + PrivateData *d; + + }; + +} + + +#endif // glbarcode_Barcode_h diff --git a/glbarcode/Barcode1dBase.cpp b/glbarcode/Barcode1dBase.cpp new file mode 100644 index 0000000..48f0f2a --- /dev/null +++ b/glbarcode/Barcode1dBase.cpp @@ -0,0 +1,117 @@ +/* Barcode1dBase.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "Barcode1dBase.h" + +#include + +#include "DrawingPrimitives.h" + + +namespace glbarcode +{ + + /* + * Barcode1dBase private data + */ + struct Barcode1dBase::PrivateData { + int dummy; + }; + + + Barcode1dBase::Barcode1dBase() + { + d = new Barcode1dBase::PrivateData; + } + + + Barcode1dBase::~Barcode1dBase() + { + delete d; + } + + + Barcode& Barcode1dBase::build( const std::string& rawData, + double w, + double h ) + { + std::string cookedData; /* Preprocessed data */ + std::string displayText; /* Text data to be displayed */ + std::string codedData; /* Encoded data */ + + clear(); + + if ( rawData.empty() ) + { + setIsEmpty( true ); + setIsDataValid( false ); + + setWidth( 0 ); + setHeight( 0 ); + } + else + { + setIsEmpty( false ); + + if ( !validate( rawData ) ) + { + setIsDataValid( false ); + + setWidth( 0 ); + setHeight( 0 ); + } + else + { + setIsDataValid( true ); + + cookedData = preprocess( rawData ); + codedData = encode( cookedData ); + displayText = prepareText( rawData ); + + vectorize( codedData, displayText, cookedData, w, h ); + + setWidth( w ); + setHeight( h ); + } + } + + return *this; + } + + + /* + * Default preprocess method + */ + std::string Barcode1dBase::preprocess( const std::string& rawData ) + { + return rawData; + } + + + /* + * Default prepareText method + */ + std::string Barcode1dBase::prepareText( const std::string& rawData ) + { + return rawData; + } + + +} diff --git a/glbarcode/Barcode1dBase.h b/glbarcode/Barcode1dBase.h new file mode 100644 index 0000000..cc28c0e --- /dev/null +++ b/glbarcode/Barcode1dBase.h @@ -0,0 +1,164 @@ +/* Barcode1dBase.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_Barcode1dBase_h +#define glbarcode_Barcode1dBase_h + + +#include + +#include "Barcode.h" +#include "Renderer.h" + + +namespace glbarcode +{ + + /** + * @class Barcode1dBase Barcode1dBase.h glbarcode/Barcode1dBase.h + * + * The Barcode1dBase class is the base class for all 1D barcode implementations. + * This class provides a common framework for the implementation of 1D barcodes. + * Creating 1D barcode types (or symbologies) would be typically accomplished by + * implementing this class rather than directly implementing the Barcode class. + * + */ + class Barcode1dBase : public Barcode + { + + protected: + /** + * Default constructor. + */ + Barcode1dBase(); + + + public: + /** + * Destructor. + */ + virtual ~Barcode1dBase(); + + + /** + * Build 1D barcode from data. + * + * Implements glbarcode::Barcode::build(). Calls the validate(), preprocess(), + * encode(), prepareText(), and vectorize() virtual methods, as shown: + * + * @dotfile figure-1d-build.dot "1D build() data flow" + * + * @param[in] data Data to encode in barcode + * @param[in] w Requested width of barcode (0 = auto size) + * @param[in] h Requested height of barcode (0 = auto size) + * + * @returns A reference to this Barcode object for chaining methods + */ + Barcode& build( const std::string& data, + double w = 0, + double h = 0 ); + + + protected: + /** + * Data validator. + * + * Required virtual method to test if data is valid for encoding with + * barcode type. + * + * @param[in] rawData Data to validate + * + * @return True if data is valid data for barcode type + * @return False if data is not valid data for barcode type + */ + virtual bool validate( const std::string& rawData ) = 0; + + + /** + * Data preprocessor. + * + * Optional virtual method to perform any transformation of the data needed + * before encoding. (E.g. encoding an extended alphabet into a simpler one). + * + * @param[in] rawData Data to preprocess + * + * @return Preprocessed data + */ + virtual std::string preprocess( const std::string& rawData ); + + + /** + * Data encoder. + * + * Required virtual method to encode data such that it can be later vectorized. + * The encoded data is usually a list of characters that represent an atomic + * barcode element (e.g. 'w' = a wide line & 'n' = a narrow line). + * + * @param[in] cookedData Data to encode + * + * @return Encoded data + */ + virtual std::string encode( const std::string& cookedData ) = 0; + + + /** + * Prepare text. + * + * Optional virtual method to prepare text to be displayed as part of barcode. + * + * @param[in] rawData Data to prepare + * + * @return text in display form + */ + virtual std::string prepareText( const std::string& rawData ); + + + /** + * Vectorize encoded data. + * + * Required virtual method to convert encoded data into a list of drawing + * primitives which can later be rendered. + * + * @param[in] encodedData Data to vectorize + * @param[in] displayText Text to display + * @param[in] cookedData Original data prior to encoding (may be needed for sizing) + * @param[in,out] w Requested width of barcode (0 = auto size), vectorize will overwrite with actual width + * @param[in,out] h Requested height of barcode (0 = auto size), vectorize will overwrite with actual width + */ + virtual void vectorize( const std::string& encodedData, + const std::string& displayText, + const std::string& cookedData, + double& w, + double& h ) = 0; + + + private: + /** + * Barcode1dBase Private data + */ + struct PrivateData; + PrivateData *d; + + }; + +} + + +#endif // glbarcode_Barcode1dBase_h diff --git a/glbarcode/Barcode2dBase.cpp b/glbarcode/Barcode2dBase.cpp new file mode 100644 index 0000000..6b4ebd5 --- /dev/null +++ b/glbarcode/Barcode2dBase.cpp @@ -0,0 +1,174 @@ +/* Barcode2dBase.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "Barcode2dBase.h" + +#include "Constants.h" +#include "DrawingPrimitives.h" + +#include + + +using namespace glbarcode::Constants; + + +namespace +{ + + const double MIN_CELL_SIZE = ( 0.0625 * PTS_PER_INCH ); + +} + + +namespace glbarcode +{ + + /* + * Barcode2dBase private data + */ + struct Barcode2dBase::PrivateData { + int dummy; + }; + + + Barcode2dBase::Barcode2dBase() + { + d = new Barcode2dBase::PrivateData; + } + + + Barcode2dBase::~Barcode2dBase() + { + delete d; + } + + + Barcode& Barcode2dBase::build( const std::string& rawData, + double w, + double h ) + { + std::string cookedData; /* Preprocessed data */ + Matrix encodedData; /* Encoded data matrix */ + + clear(); + + if ( rawData.empty() ) + { + setIsEmpty( true ); + setIsDataValid( false ); + + setWidth( 0 ); + setHeight( 0 ); + } + else + { + setIsEmpty( false ); + + if ( !validate( rawData ) ) + { + setIsDataValid( false ); + + setWidth( 0 ); + setHeight( 0 ); + } + else + { + setIsDataValid( true ); + + cookedData = preprocess( rawData ); + encode( cookedData, encodedData ); + + vectorize( encodedData, w, h ); + + setWidth( w ); + setHeight( h ); + } + } + + return *this; + } + + + /* + * Default preprocess method + */ + std::string Barcode2dBase::preprocess( const std::string& rawData ) + { + return rawData; + } + + + /* + * Default 2D vectorization method + */ + void Barcode2dBase::vectorize( const Matrix& encodedData, + double& w, + double& h ) + { + + /* determine size and establish scale */ + double scale; + double minW = MIN_CELL_SIZE*encodedData.nx() + 2*MIN_CELL_SIZE; + double minH = MIN_CELL_SIZE*encodedData.ny() + 2*MIN_CELL_SIZE; + + if ( (w <= minW) && (h <= minH) ) + { + scale = 1; + w = minW; + h = minH; + } + else if ( w <= minW ) + { + scale = h / minH; + w = scale * minW; + } + else if ( h <= minH ) + { + scale = w / minW; + h = scale * minH; + } + else + { + scale = std::min( w / minW, h / minH ); + w = scale * minW; + h = scale * minH; + } + double cellSize = scale * MIN_CELL_SIZE; + double quietSize = scale * MIN_CELL_SIZE; + + + for ( int iy = 0; iy < encodedData.ny(); iy++ ) + { + for ( int ix = 0; ix < encodedData.nx(); ix++ ) + { + if ( encodedData[iy][ix] ) + { + addBox( quietSize + ix*cellSize, + quietSize + iy*cellSize, + cellSize, + cellSize ); + } + } + } + + } + + +} diff --git a/glbarcode/Barcode2dBase.h b/glbarcode/Barcode2dBase.h new file mode 100644 index 0000000..feac1ec --- /dev/null +++ b/glbarcode/Barcode2dBase.h @@ -0,0 +1,151 @@ +/* Barcode2dBase.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_Barcode2dBase_h +#define glbarcode_Barcode2dBase_h + + +#include +#include + +#include "Barcode.h" +#include "Renderer.h" +#include "Matrix.h" + + +namespace glbarcode +{ + + /** + * @class Barcode2dBase Barcode2dBase.h glbarcode/Barcode2dBase.h + * + * The Barcode2dBase class is the base class for all 2D barcode implementations. + * This class provides a common framework for the implementation of 2D barcodes. + * Creating 2D barcode types (or symbologies) would be typically accomplished by + * implementing this class rather than directly implementing the Barcode class. + * + */ + class Barcode2dBase : public Barcode + { + + protected: + /** + * Default constructor. + */ + Barcode2dBase(); + + + public: + /** + * Destructor. + */ + virtual ~Barcode2dBase(); + + + /** + * Build 2D barcode from data. + * + * Implements glbarcode::Barcode::build(). Calls the validate(), preprocess(), + * encode(), and vectorize() virtual methods, as shown: + * + * @dotfile figure-2d-build.dot "2D build() data flow" + * + * @param[in] data Data to encode in barcode + * @param[in] w Requested width of barcode (0 = auto size) + * @param[in] h Requested height of barcode (0 = auto size) + * + * @returns A reference to this Barcode object for chaining methods + */ + Barcode& build( const std::string& data, + double w = 0, + double h = 0 ); + + + protected: + /** + * Validate barcode data. + * + * Required virtual method to test if data is valid for encoding with + * barcode type. + * + * @param[in] rawData Data to validate + * + * @return True if data is valid data for barcode type + * @return False if data is not valid data for barcode type + */ + virtual bool validate( const std::string& rawData ) = 0; + + + /** + * Preprocess barcode data. + * + * Optional virtual method to perform any transformation of the data needed + * before encoding. (E.g. encoding an extended alphabet into a simpler one). + * + * @param[in] rawData Data to preprocess + * + * @return Preprocessed data + */ + virtual std::string preprocess( const std::string& rawData ); + + + /** + * Encode barcode data + * + * Required virtual method to encode data such that it can be later vectorized. + * + * @param[in] cookedData Data to encode + * @param[out] encodedData Encoded data in the form of a matrix + * + * @return True if data was encoded successfully + * @return False if data could not be encoded (condition not discoverable by validate()) + */ + virtual bool encode( const std::string& cookedData, + Matrix& encodedData ) = 0; + + + /** + * Vectorize encoded data + * + * Optional virtual method to convert encoded data into a list of drawing + * primitives which can later be rendered. + * + * @param[in] encodedData Data to vectorize + * @param[in,out] w Requested width of barcode (0 = auto size), vectorize will overwrite with actual width + * @param[in,out] h Requested height of barcode (0 = auto size), vectorize will overwrite with actual width + */ + virtual void vectorize( const Matrix& encodedData, + double& w, + double& h ); + + + private: + /** + * Barcode2dBase Private data + */ + struct PrivateData; + PrivateData *d; + + }; + +} + + +#endif // glbarcode_Barcode2dBase_h diff --git a/glbarcode/BarcodeCepnet.cpp b/glbarcode/BarcodeCepnet.cpp new file mode 100644 index 0000000..964ce17 --- /dev/null +++ b/glbarcode/BarcodeCepnet.cpp @@ -0,0 +1,44 @@ +/* BarcodeCepnet.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodeCepnet.h" + + +namespace glbarcode +{ + + /* + * Static CEPNET barcode creation method + */ + Barcode* BarcodeCepnet::create( void ) + { + return new BarcodeCepnet(); + } + + + /* + * CEPNET validation of number of digits, overrides BarcodePostnet::validateDigits() + */ + bool BarcodeCepnet::validateDigits( int nDigits ) + { + return nDigits == 8; + } + +} diff --git a/glbarcode/BarcodeCepnet.h b/glbarcode/BarcodeCepnet.h new file mode 100644 index 0000000..d5044c7 --- /dev/null +++ b/glbarcode/BarcodeCepnet.h @@ -0,0 +1,66 @@ +/* BarcodeCepnet.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeCepnet_h +#define glbarcode_BarcodeCepnet_h + + +#include "BarcodePostnet.h" + + +namespace glbarcode +{ + + /** + * @class BarcodeCepnet BarcodeCepnet.h glbarcode/BarcodeCepnet.h + * + * 8 digit *CEPNET* barcode (Brazillian Post, based on POSTNET), extends BarcodePostnet + * + * @image html sample-cepnet.svg "Sample Brazillian Post CEPNET Barcode" + * + * + * ### Input Data Format ### + * + * Input data requirements are identical to BarcodePostnet, except the + * validator only accepts 8 digits of input. + * + * See BarcodePostnet. + * + */ + class BarcodeCepnet : public BarcodePostnet + { + public: + /** + * Static CEPNET barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validateDigits( int nDigits ); + + }; + +} + + +#endif // glbarcode_BarcodeCepnet_h diff --git a/glbarcode/BarcodeCode39.cpp b/glbarcode/BarcodeCode39.cpp new file mode 100644 index 0000000..e1f2e2e --- /dev/null +++ b/glbarcode/BarcodeCode39.cpp @@ -0,0 +1,287 @@ +/* BarcodeCode39.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodeCode39.h" + +#include "Constants.h" + +#include +#include + + +using namespace glbarcode::Constants; + + +namespace +{ + /* Code 39 alphabet. Position indicates value. */ + const std::string alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; + + /* Code 39 symbols. Position must match position in alphabet. */ + const std::string symbols[] = { + /* BsBsBsBsB */ + /* 0 */ "NnNwWnWnN", + /* 1 */ "WnNwNnNnW", + /* 2 */ "NnWwNnNnW", + /* 3 */ "WnWwNnNnN", + /* 4 */ "NnNwWnNnW", + /* 5 */ "WnNwWnNnN", + /* 6 */ "NnWwWnNnN", + /* 7 */ "NnNwNnWnW", + /* 8 */ "WnNwNnWnN", + /* 9 */ "NnWwNnWnN", + /* A */ "WnNnNwNnW", + /* B */ "NnWnNwNnW", + /* C */ "WnWnNwNnN", + /* D */ "NnNnWwNnW", + /* E */ "WnNnWwNnN", + /* F */ "NnWnWwNnN", + /* G */ "NnNnNwWnW", + /* H */ "WnNnNwWnN", + /* I */ "NnWnNwWnN", + /* J */ "NnNnWwWnN", + /* K */ "WnNnNnNwW", + /* L */ "NnWnNnNwW", + /* M */ "WnWnNnNwN", + /* N */ "NnNnWnNwW", + /* O */ "WnNnWnNwN", + /* P */ "NnWnWnNwN", + /* Q */ "NnNnNnWwW", + /* R */ "WnNnNnWwN", + /* S */ "NnWnNnWwN", + /* T */ "NnNnWnWwN", + /* U */ "WwNnNnNnW", + /* V */ "NwWnNnNnW", + /* W */ "WwWnNnNnN", + /* X */ "NwNnWnNnW", + /* Y */ "WwNnWnNnN", + /* Z */ "NwWnWnNnN", + /* - */ "NwNnNnWnW", + /* . */ "WwNnNnWnN", + /* */ "NwWnNnWnN", + /* $ */ "NwNwNwNnN", + /* / */ "NwNwNnNwN", + /* + */ "NwNnNwNwN", + /* % */ "NnNwNwNwN" + }; + + const std::string frameSymbol = "NwNnWnWnN"; + + /* Vectorization constants */ + const double MIN_X = ( 0.01 * PTS_PER_INCH ); + const double N = 2.5; + const double MIN_I = MIN_X; + const double MIN_HEIGHT = ( 0.25 * PTS_PER_INCH ); + const double MIN_QUIET = ( 0.10 * PTS_PER_INCH ); + + const double MIN_TEXT_AREA_HEIGHT = 14.0; + const double MIN_TEXT_SIZE = 10.0; + +} + + +namespace glbarcode +{ + + /* + * Static Code39 barcode creation method + */ + Barcode* BarcodeCode39::create( void ) + { + return new BarcodeCode39(); + } + + + /* + * Code39 data validation, implements Barcode1dBase::validate() + */ + bool BarcodeCode39::validate( const std::string& rawData ) + { + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + char c = toupper( rawData[i] ); + + if ( alphabet.find(c) == std::string::npos ) + { + return false; + } + } + + return true; + } + + + /* + * Code39 data encoding, implements Barcode1dBase::encode() + */ + std::string BarcodeCode39::encode( const std::string& cookedData ) + { + std::string code; + + /* Left frame symbol */ + code += frameSymbol; + code += "i"; + + int sum = 0; + for ( unsigned int i=0; i < cookedData.size(); i++ ) + { + int cValue = alphabet.find( toupper( cookedData[i] ) ); + + code += symbols[cValue]; + code += "i"; + + sum += cValue; + } + + if ( checksum() ) + { + code += symbols[sum % 43]; + code += "i"; + } + + /* Right frame bar */ + code += frameSymbol; + + return code; + } + + + /* + * Code39 prepare text for display, implements Barcode1dBase::prepareText() + */ + std::string BarcodeCode39::prepareText( const std::string& rawData ) + { + std::string displayText; + + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + displayText += toupper( rawData[i] ); + } + + return displayText; + } + + + /* + * Code39 vectorization, implements Barcode1dBase::vectorize() + */ + void BarcodeCode39::vectorize( const std::string& codedData, + const std::string& displayText, + const std::string& cookedData, + double& w, + double& h ) + { + + /* determine width and establish horizontal scale, based on original cooked data */ + double dataSize = cookedData.size(); + double minL; + if ( !checksum() ) + { + minL = (dataSize + 2)*(3*N + 6)*MIN_X + (dataSize + 1)*MIN_I; + } + else + { + minL = (dataSize + 3)*(3*N + 6)*MIN_X + (dataSize + 2)*MIN_I; + } + + double scale; + if ( w == 0 ) + { + scale = 1.0; + } + else + { + scale = w / (minL + 2*MIN_QUIET); + + if ( scale < 1.0 ) + { + scale = 1.0; + } + } + double width = minL * scale; + + /* determine text parameters */ + double hTextArea = scale * MIN_TEXT_AREA_HEIGHT; + double textSize = scale * MIN_TEXT_SIZE; + + /* determine height of barcode */ + double height = showText() ? h - hTextArea : h; + height = std::max( height, std::max( 0.15*width, MIN_HEIGHT ) ); + + /* determine horizontal quiet zone */ + double xQuiet = std::max( (10 * scale * MIN_X), MIN_QUIET ); + + /* Now traverse the code string and draw each bar */ + double x1 = xQuiet; + for ( unsigned int i=0; i < codedData.size(); i++ ) + { + double lwidth; + + switch ( codedData[i] ) + { + + case 'i': + /* Inter-character gap */ + x1 += scale * MIN_I; + break; + + case 'N': + /* Narrow bar */ + lwidth = scale*MIN_X; + addLine( x1, 0.0, lwidth, height ); + x1 += scale * MIN_X; + break; + + case 'W': + /* Wide bar */ + lwidth = scale*N*MIN_X; + addLine( x1, 0.0, lwidth, height ); + x1 += scale * N * MIN_X; + break; + + case 'n': + /* Narrow space */ + x1 += scale * MIN_X; + break; + + case 'w': + /* Wide space */ + x1 += scale * N * MIN_X; + break; + + default: + // NOT REACHED + break; + } + } + + if ( showText() ) + { + std::string starredText = "*" + displayText + "*"; + addText( xQuiet + width/2, height + (hTextArea+0.7*textSize)/2, textSize, starredText ); + } + + /* Overwrite requested size with actual size. */ + w = width + 2*xQuiet; + h = showText() ? height + hTextArea : height; + + } + +} diff --git a/glbarcode/BarcodeCode39.h b/glbarcode/BarcodeCode39.h new file mode 100644 index 0000000..fd62526 --- /dev/null +++ b/glbarcode/BarcodeCode39.h @@ -0,0 +1,100 @@ +/* BarcodeCode39.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeCode39_h +#define glbarcode_BarcodeCode39_h + + +#include "Barcode1dBase.h" + + +namespace glbarcode +{ + + /** + * @class BarcodeCode39 BarcodeCode39.h glbarcode/BarcodeCode39.h + * + * *Code 39* 1D barcode symbology. + * + * @image html sample-code39.svg "Sample Code 39 Barcode" + * + * + * ### Input Data Format ### + * + * The *Code 39* specification defines 43 characters, consisting of upper + * case letters (A-Z), decimal digits (0-9), space, and several special + * characters (-.$/+%). The BarcodeCode39 validator will also accept + * lower case letters (a-z). The encoder will automatically upshift + * any lower case letters prior to encoding. + * + * For full ASCII support see BarcodeCode39Ext. + * + * + * ### Checksum Property ### + * + * If the *checksum* property is *true*, a modulo 43 check digit will be + * automatically generated and appended to input data before encoding. + * By default, the check digit will not be generated. + * + * See setChecksum(). + * + * + * ### Show Text Property ### + * + * If the *Show Text* property is *true*, the input data will be printed + * below the barcode. By default, the data will not be printed. + * + * See setShowText(). + * + * + * ### References ### + * + * - http://en.wikipedia.org/wiki/Code_39 + * + */ + class BarcodeCode39 : public Barcode1dBase + { + public: + /** + * Static Code39 barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validate( const std::string& rawData ); + + std::string encode( const std::string& cookedData ); + + std::string prepareText( const std::string& rawData ); + + void vectorize( const std::string& codedData, + const std::string& displayText, + const std::string& cookedData, + double& w, + double& h ); + }; + +} + + +#endif // glbarcode_BarcodeCode39_h diff --git a/glbarcode/BarcodeCode39Ext.cpp b/glbarcode/BarcodeCode39Ext.cpp new file mode 100644 index 0000000..e21c8a3 --- /dev/null +++ b/glbarcode/BarcodeCode39Ext.cpp @@ -0,0 +1,118 @@ +/* BarcodeCode39Ext.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodeCode39Ext.h" + + +namespace +{ + /* Code 39Ext ASCII map. */ + const std::string asciiMap[] = { + /* NUL */ "%U", /* SOH */ "$A", /* STX */ "$B", /* ETX */ "$C", + /* EOT */ "$D", /* ENQ */ "$E", /* ACK */ "$F", /* BEL */ "$G", + /* BS */ "$H", /* HT */ "$I", /* LF */ "$J", /* VT */ "$K", + /* FF */ "$L", /* CR */ "$M", /* SO */ "$N", /* SI */ "$O", + /* DLE */ "$P", /* DC1 */ "$Q", /* DC2 */ "$R", /* DC3 */ "$S", + /* DC4 */ "$T", /* NAK */ "$U", /* SYN */ "$V", /* ETB */ "$W", + /* CAN */ "$X", /* EM */ "$Y", /* SUB */ "$Z", /* ESC */ "%A", + /* FS */ "%B", /* GS */ "%C", /* RS */ "%D", /* US */ "%E", + /* " " */ " ", /* ! */ "/A", /* " */ "/B", /* # */ "/C", + /* $ */ "/D", /* % */ "/E", /* & */ "/F", /* ' */ "/G", + /* ( */ "/H", /* ) */ "/I", /* * */ "/J", /* + */ "/K", + /* , */ "/L", /* - */ "-", /* . */ ".", /* / */ "/O", + /* 0 */ "0", /* 1 */ "1", /* 2 */ "2", /* 3 */ "3", + /* 4 */ "4", /* 5 */ "5", /* 6 */ "6", /* 7 */ "7", + /* 8 */ "8", /* 9 */ "9", /* : */ "/Z", /* ; */ "%F", + /* < */ "%G", /* = */ "%H", /* > */ "%I", /* ? */ "%J", + /* @ */ "%V", /* A */ "A", /* B */ "B", /* C */ "C", + /* D */ "D", /* E */ "E", /* F */ "F", /* G */ "G", + /* H */ "H", /* I */ "I", /* J */ "J", /* K */ "K", + /* L */ "L", /* M */ "M", /* N */ "N", /* O */ "O", + /* P */ "P", /* Q */ "Q", /* R */ "R", /* S */ "S", + /* T */ "T", /* U */ "U", /* V */ "V", /* W */ "W", + /* X */ "X", /* Y */ "Y", /* Z */ "Z", /* [ */ "%K", + /* \ */ "%L", /* ] */ "%M", /* ^ */ "%N", /* _ */ "%O", + /* ` */ "%W", /* a */ "+A", /* b */ "+B", /* c */ "+C", + /* d */ "+D", /* e */ "+E", /* f */ "+F", /* g */ "+G", + /* h */ "+H", /* i */ "+I", /* j */ "+J", /* k */ "+K", + /* l */ "+L", /* m */ "+M", /* n */ "+N", /* o */ "+O", + /* p */ "+P", /* q */ "+Q", /* r */ "+R", /* s */ "+S", + /* t */ "+T", /* u */ "+U", /* v */ "+V", /* w */ "+W", + /* x */ "+X", /* y */ "+Y", /* z */ "+Z", /* { */ "%P", + /* | */ "%Q", /* } */ "%R", /* ~ */ "%S", /* DEL */ "%T" + }; +} + + +namespace glbarcode +{ + + /* + * Static Extended Code39 barcode creation method + */ + Barcode* BarcodeCode39Ext::create( void ) + { + return new BarcodeCode39Ext(); + } + + + /* + * Extended Code39 data validation, overrides BarcodeCode39::validate() implementation + */ + bool BarcodeCode39Ext::validate( const std::string& rawData ) + { + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + if ( (rawData[i] < 0) || (rawData[i] > 0x7F) ) + { + return false; + } + } + + return true; + } + + + /* + * Extened Code39 preprocessing of data, implements Barcode1dBase::preprocess() + */ + std::string BarcodeCode39Ext::preprocess( const std::string& rawData ) + { + std::string cookedData; + + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + cookedData += asciiMap[ int(rawData[i]) ]; + } + + return cookedData; + } + + + /* + * Extended Code39 prepare text for display, overrides BarcodeCode39::prepareText() + */ + std::string BarcodeCode39Ext::prepareText( const std::string& rawData ) + { + return rawData; + } + + +} diff --git a/glbarcode/BarcodeCode39Ext.h b/glbarcode/BarcodeCode39Ext.h new file mode 100644 index 0000000..5ec0732 --- /dev/null +++ b/glbarcode/BarcodeCode39Ext.h @@ -0,0 +1,132 @@ +/* BarcodeCode39Ext.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeCode39Ext_h +#define glbarcode_BarcodeCode39Ext_h + + +#include "BarcodeCode39.h" + + +namespace glbarcode +{ + + /** + * @class BarcodeCode39Ext BarcodeCode39Ext.h glbarcode/BarcodeCode39Ext.h + * + * Extended *Code 39* 1D barcode symbology. + * + * @image html sample-code39ext.svg "Sample Extended Code 39 Barcode" + * + * + * ### Input Data Format ### + * + * The extended *Code 39* barcode type supports the full 7-bit ASCII + * character set (0-127). This support is accomplished by encoding + * lower case letters, constrol characters, and special characters + * other than "-" and "." as two character sequences as illustrated + * in the following table: + * + * | Dec | Char | Enc || Dec | Char | Enc || Dec | Char | Enc || Dec | Char | Enc | + * |----:|:----:|:---:||----:|:----:|:---:||----:|:----:|:---:||----:|:----:|:---:| + * | 0 | NUL | %%U || 32 | \" \"|\" \"|| 64 | @ | %%V || 96 | ` | %%W | + * | 1 | SOH | $A || 33 | ! | /A || 65 | A | A || 97 | a | +A | + * | 2 | STX | $B || 34 | \" | /B || 66 | B | B || 98 | b | +B | + * | 3 | ETX | $C || 35 | # | /C || 67 | C | C || 99 | c | +C | + * | 4 | EOT | $D || 36 | $ | /D || 68 | D | D || 100 | d | +D | + * | 5 | ENQ | $E || 37 | % | /E || 69 | E | E || 101 | e | +E | + * | 6 | ACK | $F || 38 | & | /F || 70 | F | F || 102 | f | +F | + * | 7 | BEL | $G || 39 | ' | /G || 71 | G | G || 103 | g | +G | + * | 8 | BS | $H || 40 | ( | /H || 72 | H | H || 104 | h | +H | + * | 9 | HT | $I || 41 | ) | /I || 73 | I | I || 105 | i | +I | + * | 10 | LF | $J || 42 | * | /J || 74 | J | J || 106 | j | +J | + * | 11 | VT | $K || 43 | + | /K || 75 | K | K || 107 | k | +K | + * | 12 | FF | $L || 44 | , | /L || 76 | L | L || 108 | l | +L | + * | 13 | CR | $M || 45 | - | - || 77 | M | M || 109 | m | +M | + * | 14 | SO | $N || 46 | . | . || 78 | N | N || 110 | n | +N | + * | 15 | SI | $O || 47 | / | /O || 79 | O | O || 111 | o | +O | + * | 16 | DLE | $P || 48 | 0 | 0 || 80 | P | P || 112 | p | +P | + * | 17 | DC1 | $Q || 49 | 1 | 1 || 81 | Q | Q || 113 | q | +Q | + * | 18 | DC2 | $R || 50 | 2 | 2 || 82 | R | R || 114 | r | +R | + * | 19 | DC3 | $S || 51 | 3 | 3 || 83 | S | S || 115 | s | +S | + * | 20 | DC4 | $T || 52 | 4 | 4 || 84 | T | T || 116 | t | +T | + * | 21 | NAK | $U || 53 | 5 | 5 || 85 | U | U || 117 | u | +U | + * | 22 | SYN | $V || 54 | 6 | 6 || 86 | V | V || 118 | v | +V | + * | 23 | ETB | $W || 55 | 7 | 7 || 87 | W | W || 119 | w | +W | + * | 24 | CAN | $X || 56 | 8 | 8 || 88 | X | X || 120 | x | +X | + * | 25 | EM | $Y || 57 | 9 | 9 || 89 | Y | Y || 121 | y | +Y | + * | 26 | SUB | $Z || 58 | : | /Z || 90 | Z | Z || 122 | z | +Z | + * | 27 | ESC | %%A || 59 | ; | %%F || 91 | [ | %%K || 123 | { | %%P | + * | 28 | FS | %%B || 60 | < | %%G || 92 | \\ | %%L || 124 | \| | %%Q | + * | 29 | GS | %%C || 61 | = | %%H || 93 | ] | %%M || 125 | } | %%R | + * | 30 | RS | %%D || 62 | > | %%I || 94 | ^ | %%N || 126 | ~ | %%S | + * | 31 | US | %%E || 63 | ? | %%J || 95 | _ | %%O || 127 | DEL | %%T | + * + * This pre-encoded data is now encoded using the standard *Code 39* symbology. + * + * + * ### Checksum Property ### + * + * If the *checksum* property is *true*, a modulo 43 check digit will be + * automatically generated and appended to the 1st pass encoded data + * prior to the 2nd pass *Code 39* encoding. By default, the check digit + * will not be generated. + * + * See setChecksum(). + * + * + * ### Show Text Property ### + * + * If the *Show Text* property is *true*, the original ASCII input data will + * be printed below the barcode. By default, the data will not be printed. + * + * See setShowText(). + * + * + * ### References ### + * + * - http://en.wikipedia.org/wiki/Code_39 + * + * + */ + class BarcodeCode39Ext : public BarcodeCode39 + { + public: + /** + * Static Extended Code39 barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validate( const std::string& rawData ); + + std::string preprocess( const std::string& rawData ); + + std::string prepareText( const std::string& rawData ); + + }; + +} + + +#endif // glbarcode_BarcodeCode39Ext_h diff --git a/glbarcode/BarcodeDataMatrix.cpp b/glbarcode/BarcodeDataMatrix.cpp new file mode 100644 index 0000000..056fe03 --- /dev/null +++ b/glbarcode/BarcodeDataMatrix.cpp @@ -0,0 +1,666 @@ +/* BarcodeDataMatrix.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodeDataMatrix.h" + +#include "Constants.h" + +#include +#include +#include +#include + + +using namespace glbarcode; +using namespace glbarcode::Constants; + + +namespace +{ + /* ASCII Encoding Codeword values */ + const uint8_t CW_PAD = 129; + const uint8_t CW_NUM_00 = 130; + const uint8_t CW_UPSHIFT = 235; + + + typedef struct + { + int nDataTotal; + int nXtotal; + int nYtotal; + int nBlocks1; + int nBlocks2; + int nDataBlock1; + int nDataBlock2; + int nEccBlock; + int aSelect; + int nXregions; + int nYregions; + int nXregion; + int nYregion; + } DMParameterEntry; + + const DMParameterEntry params[] = + { + { 3, 10, 10, 1, 0, 3, 0, 5, 0, 1, 1, 8, 8 }, + { 5, 12, 12, 1, 0, 5, 0, 7, 1, 1, 1, 10, 10 }, + { 8, 14, 14, 1, 0, 8, 0, 10, 2, 1, 1, 12, 12 }, + { 12, 16, 16, 1, 0, 12, 0, 12, 4, 1, 1, 14, 14 }, + { 18, 18, 18, 1, 0, 18, 0, 14, 5, 1, 1, 16, 16 }, + { 22, 20, 20, 1, 0, 22, 0, 18, 6, 1, 1, 18, 18 }, + { 30, 22, 22, 1, 0, 30, 0, 20, 7, 1, 1, 20, 20 }, + { 36, 24, 24, 1, 0, 36, 0, 24, 8, 1, 1, 22, 22 }, + { 44, 26, 26, 1, 0, 44, 0, 28, 9, 1, 1, 24, 24 }, + { 62, 32, 32, 1, 0, 62, 0, 36, 10, 2, 2, 14, 14 }, + { 86, 36, 36, 1, 0, 86, 0, 42, 11, 2, 2, 16, 16 }, + { 114, 40, 40, 1, 0, 114, 0, 48, 12, 2, 2, 18, 18 }, + { 144, 44, 44, 1, 0, 144, 0, 56, 13, 2, 2, 20, 20 }, + { 174, 48, 48, 1, 0, 174, 0, 68, 15, 2, 2, 22, 22 }, + { 204, 52, 52, 2, 0, 102, 0, 42, 11, 2, 2, 24, 24 }, + { 280, 64, 64, 2, 0, 140, 0, 56, 13, 4, 4, 14, 14 }, + { 368, 72, 72, 4, 0, 92, 0, 36, 10, 4, 4, 16, 16 }, + { 456, 80, 80, 4, 0, 114, 0, 48, 12, 4, 4, 18, 18 }, + { 576, 88, 88, 4, 0, 144, 0, 56, 13, 4, 4, 20, 20 }, + { 696, 96, 96, 4, 0, 174, 0, 68, 15, 4, 4, 22, 22 }, + { 816, 104, 104, 6, 0, 136, 0, 56, 13, 4, 4, 24, 24 }, + { 1050, 120, 120, 6, 0, 175, 0, 68, 15, 6, 6, 18, 18 }, + { 1304, 132, 132, 8, 0, 163, 0, 62, 14, 6, 6, 20, 20 }, + { 1558, 144, 144, 8, 2, 156, 155, 62, 14, 6, 6, 22, 22 }, + { 9999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* End of Table */ + }; + + + const uint8_t a[16][68] = + { + /* 0. Factor table for 5 RS codewords */ + { + 62, 111, 15, 48, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 1. Factor table for 7 RS codewords */ + { + 254, 92, 240, 134, 144, 68, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + + /* 2. Factor table for 10 RS codewords */ + { + 61, 110, 255, 116, 248, 223, 166, 185, 24, 28, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + + /* 3. Factor table for 11 RS codewords */ + { + 120, 97, 60, 245, 39, 168, 194, 12, 205, 138, 175, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + + /* 4. Factor table for 12 RS codewords */ + { + 242, 100, 178, 97, 213, 142, 42, 61, 91, 158, 153, 41, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + + /* 5. Factor table for 14 RS codewords */ + { + 185, 83, 186, 18, 45, 138, 119, 157, 9, 95, 252, 192, 97, 156, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + + /* 6. Factor table for 18 RS codewords */ + { + 188, 90, 48, 225, 254, 94, 129, 109, 213, 241, 61, 66, 75, 188, 39, 100, 195, + 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 7. Factor table for 20 RS codewords */ + { + 172, 186, 174, 27, 82, 108, 79, 253, 145, 153, 160, 188, 2, 168, 71, 233, 9, + 244, 195, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 8. Factor table for 24 RS codewords */ + { + 193, 50, 96, 184, 181, 12, 124, 254, 172, 5, 21, 155, 223, 251, 197, 155, 21, + 176, 39, 109, 205, 88, 190, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 9. Factor table for 28 RS codewords */ + { + 255, 93, 168, 233, 151, 120, 136, 141, 213, 110, 138, 17, 121, 249, 34, 75, 53, + 170, 151, 37, 174, 103, 96, 71, 97, 43, 231, 211, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 10. Factor table for 36 RS codewords */ + { + 112, 81, 98, 225, 25, 59, 184, 175, 44, 115, 119, 95, 137, 101, 33, 68, 4, + 2, 18, 229, 182, 80, 251, 220, 179, 84, 120, 102, 181, 162, 250, 130, 218, 242, + 127, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 11. Factor table for 42 RS codewords */ + { + 5, 9, 5, 226, 177, 150, 50, 69, 202, 248, 101, 54, 57, 253, 1, 21, 121, + 57, 111, 214, 105, 167, 9, 100, 95, 175, 8, 242, 133, 245, 2, 122, 105, 247, + 153, 22, 38, 19, 31, 137, 193, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 12. Factor table for 48 RS codewords */ + { + 19, 225, 253, 92, 213, 69, 175, 160, 147, 187, 87, 176, 44, 82, 240, 186, 138, + 66, 100, 120, 88, 131, 205, 170, 90, 37, 23, 118, 147, 16, 106, 191, 87, 237, + 188, 205, 231, 238, 133, 238, 22, 117, 32, 96, 223, 172, 132, 245, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 13. Factor table for 56 RS codewords */ + { + 46, 143, 53, 233, 107, 203, 43, 155, 28, 247, 67, 127, 245, 137, 13, 164, 207, + 62, 117, 201, 150, 22, 238, 144, 232, 29, 203, 117, 234, 218, 146, 228, 54, 132, + 200, 38, 223, 36, 159, 150, 235, 215, 192, 230, 170, 175, 29, 100, 208, 220, 17, + 12, 238, 223, 9, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + + /* 14. Factor table for 62 RS codewords */ + { + 204, 11, 47, 86, 124, 224, 166, 94, 7, 232, 107, 4, 170, 176, 31, 163, 17, + 188, 130, 40, 10, 87, 63, 51, 218, 27, 6, 147, 44, 161, 71, 114, 64, 175, + 221, 185, 106, 250, 190, 197, 63, 245, 230, 134, 112, 185, 37, 196, 108, 143, 189, + 201, 188, 202, 118, 39, 210, 144, 50, 169, 93, 242, 0, 0, 0, 0, 0, 0 + }, + + /* 15. Factor table for 68 RS codewords */ + { + 186, 82, 103, 96, 63, 132, 153, 108, 54, 64, 189, 211, 232, 49, 25, 172, 52, + 59, 241, 181, 239, 223, 136, 231, 210, 96, 232, 220, 25, 179, 167, 202, 185, 153, + 139, 66, 236, 227, 160, 15, 213, 93, 122, 68, 177, 158, 197, 234, 180, 248, 136, + 213, 127, 73, 36, 154, 244, 147, 33, 89, 56, 159, 149, 251, 89, 173, 228, 220 + } + }; + + + const int Log[] = + { + -255, 255, 1, 240, 2, 225, 241, 53, 3, 38, 226, 133, 242, 43, 54, 210, + 4, 195, 39, 114, 227, 106, 134, 28, 243, 140, 44, 23, 55, 118, 211, 234, + 5, 219, 196, 96, 40, 222, 115, 103, 228, 78, 107, 125, 135, 8, 29, 162, + 244, 186, 141, 180, 45, 99, 24, 49, 56, 13, 119, 153, 212, 199, 235, 91, + 6, 76, 220, 217, 197, 11, 97, 184, 41, 36, 223, 253, 116, 138, 104, 193, + 229, 86, 79, 171, 108, 165, 126, 145, 136, 34, 9, 74, 30, 32, 163, 84, + 245, 173, 187, 204, 142, 81, 181, 190, 46, 88, 100, 159, 25, 231, 50, 207, + 57, 147, 14, 67, 120, 128, 154, 248, 213, 167, 200, 63, 236, 110, 92, 176, + 7, 161, 77, 124, 221, 102, 218, 95, 198, 90, 12, 152, 98, 48, 185, 179, + 42, 209, 37, 132, 224, 52, 254, 239, 117, 233, 139, 22, 105, 27, 194, 113, + 230, 206, 87, 158, 80, 189, 172, 203, 109, 175, 166, 62, 127, 247, 146, 66, + 137, 192, 35, 252, 10, 183, 75, 216, 31, 83, 33, 73, 164, 144, 85, 170, + 246, 65, 174, 61, 188, 202, 205, 157, 143, 169, 82, 72, 182, 215, 191, 251, + 47, 178, 89, 151, 101, 94, 160, 123, 26, 112, 232, 21, 51, 238, 208, 131, + 58, 69, 148, 18, 15, 16, 68, 17, 121, 149, 129, 19, 155, 59, 249, 70, + 214, 250, 168, 71, 201, 156, 64, 60, 237, 130, 111, 20, 93, 122, 177, 150 + }; + + + const int Alog[] = + { + 1, 2, 4, 8, 16, 32, 64, 128, 45, 90, 180, 69, 138, 57, 114, 228, + 229, 231, 227, 235, 251, 219, 155, 27, 54, 108, 216, 157, 23, 46, 92, 184, + 93, 186, 89, 178, 73, 146, 9, 18, 36, 72, 144, 13, 26, 52, 104, 208, + 141, 55, 110, 220, 149, 7, 14, 28, 56, 112, 224, 237, 247, 195, 171, 123, + 246, 193, 175, 115, 230, 225, 239, 243, 203, 187, 91, 182, 65, 130, 41, 82, + 164, 101, 202, 185, 95, 190, 81, 162, 105, 210, 137, 63, 126, 252, 213, 135, + 35, 70, 140, 53, 106, 212, 133, 39, 78, 156, 21, 42, 84, 168, 125, 250, + 217, 159, 19, 38, 76, 152, 29, 58, 116, 232, 253, 215, 131, 43, 86, 172, + 117, 234, 249, 223, 147, 11, 22, 44, 88, 176, 77, 154, 25, 50, 100, 200, + 189, 87, 174, 113, 226, 233, 255, 211, 139, 59, 118, 236, 245, 199, 163, 107, + 214, 129, 47, 94, 188, 85, 170, 121, 242, 201, 191, 83, 166, 97, 194, 169, + 127, 254, 209, 143, 51, 102, 204, 181, 71, 142, 49, 98, 196, 165, 103, 206, + 177, 79, 158, 17, 34, 68, 136, 61, 122, 244, 197, 167, 99, 198, 161, 111, + 222, 145, 15, 30, 60, 120, 240, 205, 183, 67, 134, 33, 66, 132, 37, 74, + 148, 5, 10, 20, 40, 80, 160, 109, 218, 153, 31, 62, 124, 248, 221, 151, + 3, 6, 12, 24, 48, 96, 192, 173, 119, 238, 241, 207, 179, 75, 150, 1 + }; + + + int ecc200Encode( const std::string& data, std::vector& codewords ) + { + /* + * Encode data into codewords using ASCII encoding method. + */ + for ( unsigned int i = 0; i < data.size(); i++ ) + { + uint8_t c = data[i]; + + if ( c < 128 ) + { + uint8_t c1 = data[i+1]; + + if ( (i < (data.size()-1)) && isdigit(c) && isdigit(c1) ) + { + /* 2-digit data 00 - 99 */ + codewords.push_back( CW_NUM_00 + (c-'0')*10 + (c1-'0') ); + i++; /* skip next input char */ + } + else + { + /* Simple ASCII data (ASCII value + 1) */ + codewords.push_back( c + 1 ); + } + } + else + { + /* Extended ASCII range (128-255) */ + codewords.push_back( CW_UPSHIFT ); + codewords.push_back( c - 127 ); + } + } + + return codewords.size(); + } + + + const DMParameterEntry* ecc200BestSizeParams( int nRawCw ) + { + + if ( nRawCw > 1558 ) + { + return NULL; + } + + int iParam = 0; + + while ( nRawCw > params[iParam].nDataTotal ) + { + iParam++; + } + + return ¶ms[iParam]; + } + + + void ecc200Fill( std::vector& codewords, int nRawCw, int nDataTotal ) + { + int nFillCw = nDataTotal - nRawCw; + + if ( nFillCw > 0 ) + { + codewords.push_back( CW_PAD ); + } + + for ( int i = nRawCw + 1; i < nDataTotal; i++ ) + { + int r = (149*(i+1))%253 + 1; + codewords.push_back( (CW_PAD + r) % 254 ); + } + } + + + void ecc200EccBlock( const std::vector& codewords, + std::vector& ecc, + int n, + int nc, + int aSelect, + int offset, + int stride ) + { + for ( int i = 0; i < n; i++ ) + { + uint8_t k = ecc[offset] ^ codewords[i*stride + offset]; + + for ( int j = 0; j < (nc-1); j++ ) + { + uint8_t c = a[aSelect][j]; + + if ( k != 0 ) + { + ecc[j*stride+offset] = ecc[(j+1)*stride + offset] ^ Alog[ (Log[k] + Log[c]) % 255 ]; + } + else + { + ecc[j*stride+offset] = ecc[(j+1)*stride + offset]; + } + } + uint8_t c = a[aSelect][nc-1]; + if ( k != 0 ) + { + ecc[(nc-1)*stride + offset] = Alog[ (Log[k] + Log[c]) % 255 ]; + } + else + { + ecc[(nc-1)*stride + offset] = 0; + } + } + } + + + void module( Matrix& matrix, + Matrix& used, + int ix, + int iy, + uint8_t codeword, + int bit ) + { + if ( iy < 0 ) + { + ix += 4 - ((matrix.ny()+4) % 8 ); + iy += matrix.ny(); + } + + if ( ix < 0 ) + { + ix += matrix.nx(); + iy += 4 - ((matrix.nx()+4) % 8 ); + } + + used[iy][ix] = true; + + if ( codeword & (1 << bit) ) + { + matrix[iy][ix] = true; + } + } + + + void corner1( Matrix& matrix, + Matrix& used, + uint8_t codeword ) + { + int nx = matrix.nx(); + int ny = matrix.ny(); + + module( matrix, used, 0, ny-1, codeword, 7 ); + module( matrix, used, 1, ny-1, codeword, 6 ); + module( matrix, used, 2, ny-1, codeword, 5 ); + module( matrix, used, nx-2, 0, codeword, 4 ); + module( matrix, used, nx-1, 0, codeword, 3 ); + module( matrix, used, nx-1, 1, codeword, 2 ); + module( matrix, used, nx-1, 2, codeword, 1 ); + module( matrix, used, nx-1, 3, codeword, 0 ); + } + + + void corner2( Matrix& matrix, + Matrix& used, + uint8_t codeword ) + { + int nx = matrix.nx(); + int ny = matrix.ny(); + + module( matrix, used, 0, ny-3, codeword, 7 ); + module( matrix, used, 0, ny-2, codeword, 6 ); + module( matrix, used, 0, ny-1, codeword, 5 ); + module( matrix, used, nx-4, 0, codeword, 4 ); + module( matrix, used, nx-3, 0, codeword, 3 ); + module( matrix, used, nx-2, 0, codeword, 2 ); + module( matrix, used, nx-1, 0, codeword, 1 ); + module( matrix, used, nx-1, 1, codeword, 0 ); + } + + + void corner3( Matrix& matrix, + Matrix& used, + uint8_t codeword ) + { + int nx = matrix.nx(); + int ny = matrix.ny(); + + module( matrix, used, 0, ny-3, codeword, 7 ); + module( matrix, used, 0, ny-2, codeword, 6 ); + module( matrix, used, 0, ny-1, codeword, 5 ); + module( matrix, used, nx-2, 0, codeword, 4 ); + module( matrix, used, nx-1, 0, codeword, 3 ); + module( matrix, used, nx-1, 1, codeword, 2 ); + module( matrix, used, nx-1, 2, codeword, 1 ); + module( matrix, used, nx-1, 3, codeword, 0 ); + } + + + void corner4( Matrix& matrix, + Matrix& used, + uint8_t codeword ) + { + int nx = matrix.nx(); + int ny = matrix.ny(); + + module( matrix, used, 0, ny-1, codeword, 7 ); + module( matrix, used, nx-1, ny-1, codeword, 6 ); + module( matrix, used, nx-3, 0, codeword, 5 ); + module( matrix, used, nx-2, 0, codeword, 4 ); + module( matrix, used, nx-1, 0, codeword, 3 ); + module( matrix, used, nx-3, 1, codeword, 2 ); + module( matrix, used, nx-2, 1, codeword, 1 ); + module( matrix, used, nx-1, 1, codeword, 0 ); + } + + + void utah( Matrix& matrix, + Matrix& used, + int ix, + int iy, + uint8_t codeword ) + { + module( matrix, used, ix-2, iy-2, codeword, 7 ); + module( matrix, used, ix-1, iy-2, codeword, 6 ); + module( matrix, used, ix-2, iy-1, codeword, 5 ); + module( matrix, used, ix-1, iy-1, codeword, 4 ); + module( matrix, used, ix, iy-1, codeword, 3 ); + module( matrix, used, ix-2, iy, codeword, 2 ); + module( matrix, used, ix-1, iy, codeword, 1 ); + module( matrix, used, ix, iy, codeword, 0 ); + } + + + void ecc200FillMatrix( Matrix& matrix, + const std::vector& codewords ) + { + matrix.fill( false ); + + Matrix used = matrix; + + int i = 0; + int ix = 0; + int iy = 4; + int nx = matrix.nx(); + int ny = matrix.ny(); + + do { + if ( (iy == ny) && (ix == 0) ) corner1( matrix, used, codewords[i++] ); + if ( (iy == ny-2) && (ix == 0) && (nx%4 != 0) ) corner2( matrix, used, codewords[i++] ); + if ( (iy == ny-2) && (ix == 0) && (nx%8 == 4) ) corner3( matrix, used, codewords[i++] ); + if ( (iy == ny+4) && (ix == 2) && (nx%8 == 0) ) corner4( matrix, used, codewords[i++] ); + + do { + if ( (iy < ny) && (ix >= 0) && !used[iy][ix] ) utah( matrix, used, ix, iy, codewords[i++] ); + ix += 2; + iy -= 2; + } while ( (iy >= 0) && (ix < nx) ); + ix += 3; + iy += 1; + + do { + if ( (iy >= 0) && (ix < nx) && !used[iy][ix] ) utah( matrix, used, ix, iy, codewords[i++] ); + ix -= 2; + iy += 2; + } while ( (iy < ny) && (ix >= 0) ); + ix += 1; + iy += 3; + + } while ( (iy < ny) || (ix < nx) ); + + if ( !used[ny-1][nx-1] ) + { + matrix[ny-1][nx-1] = true; + matrix[ny-2][nx-2] = true; + } + } + + + void finderPattern( Matrix& encodedData, int x0, int y0, int nx, int ny ) + { + for ( int ix = 0; ix < nx; ix++ ) + { + encodedData[y0+ny-1][x0+ix] = true; + } + + for ( int iy = 0; iy < ny; iy++ ) + { + encodedData[y0+iy][x0] = true; + } + + for ( int ix = 0; ix < nx; ix += 2 ) + { + encodedData[y0][x0+ix] = true; + encodedData[y0][x0+ix+1] = false; + } + + for ( int iy = 0; iy < ny; iy += 2 ) + { + encodedData[y0+iy][x0+nx-1] = false; + encodedData[y0+iy+1][x0+nx-1] = true; + } + + } + +} + + +namespace glbarcode +{ + + /* + * Static DataMatrix barcode creation method + */ + Barcode* BarcodeDataMatrix::create( void ) + { + return new BarcodeDataMatrix(); + } + + + /* + * DataMatrix data validation, implements Barcode2dBase::validate() + */ + bool BarcodeDataMatrix::validate( const std::string& rawData ) + { + return true; + } + + + /* + * DataMatrix data encoding, implements Barcode2dBase::encode() + */ + bool BarcodeDataMatrix::encode( const std::string& cookedData, Matrix& encodedData ) + { + std::vector codewords; + + /* + * Encode data into codewords + */ + int nRawCw = ecc200Encode( cookedData, codewords ); + + /* + * Determine parameters for "best size" + */ + const DMParameterEntry * p = ecc200BestSizeParams( nRawCw ); + if ( p == NULL ) + { + return false; + } + encodedData.resize( p->nXtotal, p->nYtotal ); + + + /* + * Fill any extra data codewords + */ + ecc200Fill( codewords, nRawCw, p->nDataTotal ); + + + /* + * Calculate Reed-Solomon correction codewords + */ + int nTotalBlocks = p->nBlocks1 + p->nBlocks2; + + std::vector ecc( p->nEccBlock*nTotalBlocks, 0 ); + + for ( int iBlock = 0; iBlock < p->nBlocks1; iBlock++ ) + { + ecc200EccBlock( codewords, ecc, p->nDataBlock1, p->nEccBlock, p->aSelect, iBlock, nTotalBlocks ); + } + + for ( int iBlock = p->nBlocks1; iBlock < nTotalBlocks; iBlock++ ) + { + ecc200EccBlock( codewords, ecc, p->nDataBlock2, p->nEccBlock, p->aSelect, iBlock, nTotalBlocks ); + } + + codewords.insert( codewords.end(), ecc.begin(), ecc.end() ); /* Append to data */ + + + /* + * Create raw data matrix + */ + Matrix matrix( p->nXregions * p->nXregion, p->nYregions * p->nYregion ); + ecc200FillMatrix( matrix, codewords ); + + + /* + * Construct by separating out regions and inserting finder patterns + */ + int xstride = p->nXregion + 2; + int ystride = p->nYregion + 2; + + for ( int iXregion = 0; iXregion < p->nXregions; iXregion++ ) + { + for ( int iYregion = 0; iYregion < p->nYregions; iYregion++ ) + { + Matrix region = matrix.subMatrix( iXregion*p->nXregion, iYregion*p->nYregion, + p->nXregion, p->nYregion ); + + encodedData.setSubMatrix( iXregion*xstride + 1, iYregion*ystride + 1, region ); + finderPattern( encodedData, iXregion*xstride, iYregion*ystride, xstride, ystride ); + } + } + + + return true; + } + + +} diff --git a/glbarcode/BarcodeDataMatrix.h b/glbarcode/BarcodeDataMatrix.h new file mode 100644 index 0000000..f19a03d --- /dev/null +++ b/glbarcode/BarcodeDataMatrix.h @@ -0,0 +1,61 @@ +/* BarcodeDataMatrix.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeDataMatrix_h +#define glbarcode_BarcodeDataMatrix_h + + +#include "Barcode2dBase.h" + + +namespace glbarcode +{ + + /** + * @class BarcodeDataMatrix BarcodeDataMatrix.h glbarcode/BarcodeDataMatrix.h + * + * DataMatrix barcode, implements Barcode2dBase + * + * @image html sample-datamatrix.svg "Sample Data Matrix Barcode" + * + */ + class BarcodeDataMatrix : public Barcode2dBase + { + public: + /** + * Static DataMatrix barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validate( const std::string& rawData ); + + bool encode( const std::string& cookedData, + Matrix& encodedData ); + + }; + +} + + +#endif // glbarcode_BarcodeDataMatrix_h diff --git a/glbarcode/BarcodeEan13.cpp b/glbarcode/BarcodeEan13.cpp new file mode 100644 index 0000000..6f2b0fd --- /dev/null +++ b/glbarcode/BarcodeEan13.cpp @@ -0,0 +1,95 @@ +/* BarcodeEan13.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodeEan13.h" + +#include +#include + + +namespace glbarcode +{ + + /* + * Static EAN-13 barcode creation method + */ + Barcode* BarcodeEan13::create( void ) + { + return new BarcodeEan13(); + } + + + /* + * EAN-13 barcode constructor + */ + BarcodeEan13::BarcodeEan13() + { + mEndBarsModules = 3; + } + + + /* + * EAN-13 validate number of digits, implements BarcodeUpcBase::validateDigits() + */ + bool BarcodeEan13::validateDigits( int nDigits ) + { + return (nDigits == 12); + } + + + /* + * EAN-13 Pre-process data before encoding, implements Barcode1dBase::preprocess() + */ + std::string BarcodeEan13::preprocess( const std::string& rawData ) + { + std::string cookedData; + + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + if ( isdigit( rawData[i] ) ) + { + cookedData += rawData[i]; + } + } + + mFirstDigitVal = (cookedData[0] - '0'); + return cookedData.substr( 1, cookedData.size()-1 ); + } + + + /* + * EAN-13 vectorize text, implements BarcodeUpcBase::vectorizeText() + */ + void BarcodeEan13::vectorizeText( const std::string& displayText, + double size1, + double size2, + double x1Left, + double x1Right, + double y1, + double x2Left, + double x2Right, + double y2 ) + { + addText( x2Left, y2, size2, displayText.substr( 0, 1 ) ); + addText( x1Left, y1, size1, displayText.substr( 1, 6 ) ); + addText( x1Right, y1, size1, displayText.substr( 7, 6 ) ); + } + +} diff --git a/glbarcode/BarcodeEan13.h b/glbarcode/BarcodeEan13.h new file mode 100644 index 0000000..9c075cb --- /dev/null +++ b/glbarcode/BarcodeEan13.h @@ -0,0 +1,76 @@ +/* BarcodeEan13.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeEan13_h +#define glbarcode_BarcodeEan13_h + + +#include "BarcodeUpcBase.h" + + +namespace glbarcode +{ + + /** + * @class BarcodeEan13 BarcodeEan13.h glbarcode/BarcodeEan13.h + * + * EAN-13 barcode, implements BarcodeUpcBase + * + * @image html sample-ean-13.svg "Sample EAN-13 Barcode" + * + */ + class BarcodeEan13 : public BarcodeUpcBase + { + public: + /** + * Static EAN-13 barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + /** + * Default constructor + */ + BarcodeEan13(); + + + private: + bool validateDigits( int nDigits ); + + std::string preprocess( const std::string& rawData ); + + void vectorizeText( const std::string& displayText, + double size1, + double size2, + double x1Left, + double x1Right, + double y1, + double x2Left, + double x2Right, + double y2 ); + + }; + +} + + +#endif // glbarcode_BarcodeEan13_h diff --git a/glbarcode/BarcodeOnecode.cpp b/glbarcode/BarcodeOnecode.cpp new file mode 100644 index 0000000..243da38 --- /dev/null +++ b/glbarcode/BarcodeOnecode.cpp @@ -0,0 +1,616 @@ +/* BarcodeOnecode.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodeOnecode.h" + +#include "Constants.h" + +#include +#include + + +using namespace glbarcode::Constants; + + +namespace +{ + /* + * Constants + */ + const double ONECODE_BAR_WIDTH = ( 0.02 * PTS_PER_INCH ); + const double ONECODE_FULL_HEIGHT = ( 0.145 * PTS_PER_INCH ); + const double ONECODE_ASCENDER_HEIGHT = ( 0.0965 * PTS_PER_INCH ); + const double ONECODE_DESCENDER_HEIGHT = ( 0.0965 * PTS_PER_INCH ); + const double ONECODE_TRACKER_HEIGHT = ( 0.048 * PTS_PER_INCH ); + const double ONECODE_FULL_OFFSET = 0; + const double ONECODE_ASCENDER_OFFSET = 0; + const double ONECODE_DESCENDER_OFFSET = ( 0.0485 * PTS_PER_INCH ); + const double ONECODE_TRACKER_OFFSET = ( 0.0485 * PTS_PER_INCH ); + const double ONECODE_BAR_PITCH = ( 0.0458 * PTS_PER_INCH ); + const double ONECODE_HORIZ_MARGIN = ( 0.125 * PTS_PER_INCH ); + const double ONECODE_VERT_MARGIN = ( 0.028 * PTS_PER_INCH ); + + + /* + * Encoding tables + */ + typedef enum + { + CHAR_A = 0, + CHAR_B = 1, + CHAR_C = 2, + CHAR_D = 3, + CHAR_E = 4, + CHAR_F = 5, + CHAR_G = 6, + CHAR_H = 7, + CHAR_I = 8, + CHAR_J = 9 + } Char; + + typedef struct { Char i; int mask; } Bar; + + typedef struct + { + Bar descender; + Bar ascender; + } BarMapEntry; + + const BarMapEntry barMap[] = { + /* 1 */ { { CHAR_H, 1<<2 }, { CHAR_E, 1<<3 } }, + /* 2 */ { { CHAR_B, 1<<10 }, { CHAR_A, 1<<0 } }, + /* 3 */ { { CHAR_J, 1<<12 }, { CHAR_C, 1<<8 } }, + /* 4 */ { { CHAR_F, 1<<5 }, { CHAR_G, 1<<11 } }, + /* 5 */ { { CHAR_I, 1<<9 }, { CHAR_D, 1<<1 } }, + /* 6 */ { { CHAR_A, 1<<1 }, { CHAR_F, 1<<12 } }, + /* 7 */ { { CHAR_C, 1<<5 }, { CHAR_B, 1<<8 } }, + /* 8 */ { { CHAR_E, 1<<4 }, { CHAR_J, 1<<11 } }, + /* 9 */ { { CHAR_G, 1<<3 }, { CHAR_I, 1<<10 } }, + /* 10 */ { { CHAR_D, 1<<9 }, { CHAR_H, 1<<6 } }, + /* 11 */ { { CHAR_F, 1<<11 }, { CHAR_B, 1<<4 } }, + /* 12 */ { { CHAR_I, 1<<5 }, { CHAR_C, 1<<12 } }, + /* 13 */ { { CHAR_J, 1<<10 }, { CHAR_A, 1<<2 } }, + /* 14 */ { { CHAR_H, 1<<1 }, { CHAR_G, 1<<7 } }, + /* 15 */ { { CHAR_D, 1<<6 }, { CHAR_E, 1<<9 } }, + /* 16 */ { { CHAR_A, 1<<3 }, { CHAR_I, 1<<6 } }, + /* 17 */ { { CHAR_G, 1<<4 }, { CHAR_C, 1<<7 } }, + /* 18 */ { { CHAR_B, 1<<1 }, { CHAR_J, 1<<9 } }, + /* 19 */ { { CHAR_H, 1<<10 }, { CHAR_F, 1<<2 } }, + /* 20 */ { { CHAR_E, 1<<0 }, { CHAR_D, 1<<8 } }, + /* 21 */ { { CHAR_G, 1<<2 }, { CHAR_A, 1<<4 } }, + /* 22 */ { { CHAR_I, 1<<11 }, { CHAR_B, 1<<0 } }, + /* 23 */ { { CHAR_J, 1<<8 }, { CHAR_D, 1<<12 } }, + /* 24 */ { { CHAR_C, 1<<6 }, { CHAR_H, 1<<7 } }, + /* 25 */ { { CHAR_F, 1<<1 }, { CHAR_E, 1<<10 } }, + /* 26 */ { { CHAR_B, 1<<12 }, { CHAR_G, 1<<9 } }, + /* 27 */ { { CHAR_H, 1<<3 }, { CHAR_I, 1<<0 } }, + /* 28 */ { { CHAR_F, 1<<8 }, { CHAR_J, 1<<7 } }, + /* 29 */ { { CHAR_E, 1<<6 }, { CHAR_C, 1<<10 } }, + /* 30 */ { { CHAR_D, 1<<4 }, { CHAR_A, 1<<5 } }, + /* 31 */ { { CHAR_I, 1<<4 }, { CHAR_F, 1<<7 } }, + /* 32 */ { { CHAR_H, 1<<11 }, { CHAR_B, 1<<9 } }, + /* 33 */ { { CHAR_G, 1<<0 }, { CHAR_J, 1<<6 } }, + /* 34 */ { { CHAR_A, 1<<6 }, { CHAR_E, 1<<8 } }, + /* 35 */ { { CHAR_C, 1<<1 }, { CHAR_D, 1<<2 } }, + /* 36 */ { { CHAR_F, 1<<9 }, { CHAR_I, 1<<12 } }, + /* 37 */ { { CHAR_E, 1<<11 }, { CHAR_G, 1<<1 } }, + /* 38 */ { { CHAR_J, 1<<5 }, { CHAR_H, 1<<4 } }, + /* 39 */ { { CHAR_D, 1<<3 }, { CHAR_B, 1<<2 } }, + /* 40 */ { { CHAR_A, 1<<7 }, { CHAR_C, 1<<0 } }, + /* 41 */ { { CHAR_B, 1<<3 }, { CHAR_E, 1<<1 } }, + /* 42 */ { { CHAR_G, 1<<10 }, { CHAR_D, 1<<5 } }, + /* 43 */ { { CHAR_I, 1<<7 }, { CHAR_J, 1<<4 } }, + /* 44 */ { { CHAR_C, 1<<11 }, { CHAR_F, 1<<6 } }, + /* 45 */ { { CHAR_A, 1<<8 }, { CHAR_H, 1<<12 } }, + /* 46 */ { { CHAR_E, 1<<2 }, { CHAR_I, 1<<1 } }, + /* 47 */ { { CHAR_F, 1<<10 }, { CHAR_D, 1<<0 } }, + /* 48 */ { { CHAR_J, 1<<3 }, { CHAR_A, 1<<9 } }, + /* 49 */ { { CHAR_G, 1<<5 }, { CHAR_C, 1<<4 } }, + /* 50 */ { { CHAR_H, 1<<8 }, { CHAR_B, 1<<7 } }, + /* 51 */ { { CHAR_F, 1<<0 }, { CHAR_E, 1<<5 } }, + /* 52 */ { { CHAR_C, 1<<3 }, { CHAR_A, 1<<10 } }, + /* 53 */ { { CHAR_G, 1<<12 }, { CHAR_J, 1<<2 } }, + /* 54 */ { { CHAR_D, 1<<11 }, { CHAR_B, 1<<6 } }, + /* 55 */ { { CHAR_I, 1<<8 }, { CHAR_H, 1<<9 } }, + /* 56 */ { { CHAR_F, 1<<4 }, { CHAR_A, 1<<11 } }, + /* 57 */ { { CHAR_B, 1<<5 }, { CHAR_C, 1<<2 } }, + /* 58 */ { { CHAR_J, 1<<1 }, { CHAR_E, 1<<12 } }, + /* 59 */ { { CHAR_I, 1<<3 }, { CHAR_G, 1<<6 } }, + /* 60 */ { { CHAR_H, 1<<0 }, { CHAR_D, 1<<7 } }, + /* 61 */ { { CHAR_E, 1<<7 }, { CHAR_H, 1<<5 } }, + /* 62 */ { { CHAR_A, 1<<12 }, { CHAR_B, 1<<11 } }, + /* 63 */ { { CHAR_C, 1<<9 }, { CHAR_J, 1<<0 } }, + /* 64 */ { { CHAR_G, 1<<8 }, { CHAR_F, 1<<3 } }, + /* 65 */ { { CHAR_D, 1<<10 }, { CHAR_I, 1<<2 } } + }; + + + const std::string tdafTable[] = { "T", "D", "A", "F" }; + + + const unsigned int characterTable[] = { + /* Table I 5 of 13. */ + 31, 7936, 47, 7808, 55, 7552, 59, 7040, 61, 6016, + 62, 3968, 79, 7744, 87, 7488, 91, 6976, 93, 5952, + 94, 3904, 103, 7360, 107, 6848, 109, 5824, 110, 3776, + 115, 6592, 117, 5568, 118, 3520, 121, 5056, 122, 3008, + 124, 1984, 143, 7712, 151, 7456, 155, 6944, 157, 5920, + 158, 3872, 167, 7328, 171, 6816, 173, 5792, 174, 3744, + 179, 6560, 181, 5536, 182, 3488, 185, 5024, 186, 2976, + 188, 1952, 199, 7264, 203, 6752, 205, 5728, 206, 3680, + 211, 6496, 213, 5472, 214, 3424, 217, 4960, 218, 2912, + 220, 1888, 227, 6368, 229, 5344, 230, 3296, 233, 4832, + 234, 2784, 236, 1760, 241, 4576, 242, 2528, 244, 1504, + 248, 992, 271, 7696, 279, 7440, 283, 6928, 285, 5904, + 286, 3856, 295, 7312, 299, 6800, 301, 5776, 302, 3728, + 307, 6544, 309, 5520, 310, 3472, 313, 5008, 314, 2960, + 316, 1936, 327, 7248, 331, 6736, 333, 5712, 334, 3664, + 339, 6480, 341, 5456, 342, 3408, 345, 4944, 346, 2896, + 348, 1872, 355, 6352, 357, 5328, 358, 3280, 361, 4816, + 362, 2768, 364, 1744, 369, 4560, 370, 2512, 372, 1488, + 376, 976, 391, 7216, 395, 6704, 397, 5680, 398, 3632, + 403, 6448, 405, 5424, 406, 3376, 409, 4912, 410, 2864, + 412, 1840, 419, 6320, 421, 5296, 422, 3248, 425, 4784, + 426, 2736, 428, 1712, 433, 4528, 434, 2480, 436, 1456, + 440, 944, 451, 6256, 453, 5232, 454, 3184, 457, 4720, + 458, 2672, 460, 1648, 465, 4464, 466, 2416, 468, 1392, + 472, 880, 481, 4336, 482, 2288, 484, 1264, 488, 752, + 527, 7688, 535, 7432, 539, 6920, 541, 5896, 542, 3848, + 551, 7304, 555, 6792, 557, 5768, 558, 3720, 563, 6536, + 565, 5512, 566, 3464, 569, 5000, 570, 2952, 572, 1928, + 583, 7240, 587, 6728, 589, 5704, 590, 3656, 595, 6472, + 597, 5448, 598, 3400, 601, 4936, 602, 2888, 604, 1864, + 611, 6344, 613, 5320, 614, 3272, 617, 4808, 618, 2760, + 620, 1736, 625, 4552, 626, 2504, 628, 1480, 632, 968, + 647, 7208, 651, 6696, 653, 5672, 654, 3624, 659, 6440, + 661, 5416, 662, 3368, 665, 4904, 666, 2856, 668, 1832, + 675, 6312, 677, 5288, 678, 3240, 681, 4776, 682, 2728, + 684, 1704, 689, 4520, 690, 2472, 692, 1448, 696, 936, + 707, 6248, 709, 5224, 710, 3176, 713, 4712, 714, 2664, + 716, 1640, 721, 4456, 722, 2408, 724, 1384, 728, 872, + 737, 4328, 738, 2280, 740, 1256, 775, 7192, 779, 6680, + 781, 5656, 782, 3608, 787, 6424, 789, 5400, 790, 3352, + 793, 4888, 794, 2840, 796, 1816, 803, 6296, 805, 5272, + 806, 3224, 809, 4760, 810, 2712, 812, 1688, 817, 4504, + 818, 2456, 820, 1432, 824, 920, 835, 6232, 837, 5208, + 838, 3160, 841, 4696, 842, 2648, 844, 1624, 849, 4440, + 850, 2392, 852, 1368, 865, 4312, 866, 2264, 868, 1240, + 899, 6200, 901, 5176, 902, 3128, 905, 4664, 906, 2616, + 908, 1592, 913, 4408, 914, 2360, 916, 1336, 929, 4280, + 930, 2232, 932, 1208, 961, 4216, 962, 2168, 964, 1144, + 1039, 7684, 1047, 7428, 1051, 6916, 1053, 5892, 1054, 3844, + 1063, 7300, 1067, 6788, 1069, 5764, 1070, 3716, 1075, 6532, + 1077, 5508, 1078, 3460, 1081, 4996, 1082, 2948, 1084, 1924, + 1095, 7236, 1099, 6724, 1101, 5700, 1102, 3652, 1107, 6468, + 1109, 5444, 1110, 3396, 1113, 4932, 1114, 2884, 1116, 1860, + 1123, 6340, 1125, 5316, 1126, 3268, 1129, 4804, 1130, 2756, + 1132, 1732, 1137, 4548, 1138, 2500, 1140, 1476, 1159, 7204, + 1163, 6692, 1165, 5668, 1166, 3620, 1171, 6436, 1173, 5412, + 1174, 3364, 1177, 4900, 1178, 2852, 1180, 1828, 1187, 6308, + 1189, 5284, 1190, 3236, 1193, 4772, 1194, 2724, 1196, 1700, + 1201, 4516, 1202, 2468, 1204, 1444, 1219, 6244, 1221, 5220, + 1222, 3172, 1225, 4708, 1226, 2660, 1228, 1636, 1233, 4452, + 1234, 2404, 1236, 1380, 1249, 4324, 1250, 2276, 1287, 7188, + 1291, 6676, 1293, 5652, 1294, 3604, 1299, 6420, 1301, 5396, + 1302, 3348, 1305, 4884, 1306, 2836, 1308, 1812, 1315, 6292, + 1317, 5268, 1318, 3220, 1321, 4756, 1322, 2708, 1324, 1684, + 1329, 4500, 1330, 2452, 1332, 1428, 1347, 6228, 1349, 5204, + 1350, 3156, 1353, 4692, 1354, 2644, 1356, 1620, 1361, 4436, + 1362, 2388, 1377, 4308, 1378, 2260, 1411, 6196, 1413, 5172, + 1414, 3124, 1417, 4660, 1418, 2612, 1420, 1588, 1425, 4404, + 1426, 2356, 1441, 4276, 1442, 2228, 1473, 4212, 1474, 2164, + 1543, 7180, 1547, 6668, 1549, 5644, 1550, 3596, 1555, 6412, + 1557, 5388, 1558, 3340, 1561, 4876, 1562, 2828, 1564, 1804, + 1571, 6284, 1573, 5260, 1574, 3212, 1577, 4748, 1578, 2700, + 1580, 1676, 1585, 4492, 1586, 2444, 1603, 6220, 1605, 5196, + 1606, 3148, 1609, 4684, 1610, 2636, 1617, 4428, 1618, 2380, + 1633, 4300, 1634, 2252, 1667, 6188, 1669, 5164, 1670, 3116, + 1673, 4652, 1674, 2604, 1681, 4396, 1682, 2348, 1697, 4268, + 1698, 2220, 1729, 4204, 1730, 2156, 1795, 6172, 1797, 5148, + 1798, 3100, 1801, 4636, 1802, 2588, 1809, 4380, 1810, 2332, + 1825, 4252, 1826, 2204, 1857, 4188, 1858, 2140, 1921, 4156, + 1922, 2108, 2063, 7682, 2071, 7426, 2075, 6914, 2077, 5890, + 2078, 3842, 2087, 7298, 2091, 6786, 2093, 5762, 2094, 3714, + 2099, 6530, 2101, 5506, 2102, 3458, 2105, 4994, 2106, 2946, + 2119, 7234, 2123, 6722, 2125, 5698, 2126, 3650, 2131, 6466, + 2133, 5442, 2134, 3394, 2137, 4930, 2138, 2882, 2147, 6338, + 2149, 5314, 2150, 3266, 2153, 4802, 2154, 2754, 2161, 4546, + 2162, 2498, 2183, 7202, 2187, 6690, 2189, 5666, 2190, 3618, + 2195, 6434, 2197, 5410, 2198, 3362, 2201, 4898, 2202, 2850, + 2211, 6306, 2213, 5282, 2214, 3234, 2217, 4770, 2218, 2722, + 2225, 4514, 2226, 2466, 2243, 6242, 2245, 5218, 2246, 3170, + 2249, 4706, 2250, 2658, 2257, 4450, 2258, 2402, 2273, 4322, + 2311, 7186, 2315, 6674, 2317, 5650, 2318, 3602, 2323, 6418, + 2325, 5394, 2326, 3346, 2329, 4882, 2330, 2834, 2339, 6290, + 2341, 5266, 2342, 3218, 2345, 4754, 2346, 2706, 2353, 4498, + 2354, 2450, 2371, 6226, 2373, 5202, 2374, 3154, 2377, 4690, + 2378, 2642, 2385, 4434, 2401, 4306, 2435, 6194, 2437, 5170, + 2438, 3122, 2441, 4658, 2442, 2610, 2449, 4402, 2465, 4274, + 2497, 4210, 2567, 7178, 2571, 6666, 2573, 5642, 2574, 3594, + 2579, 6410, 2581, 5386, 2582, 3338, 2585, 4874, 2586, 2826, + 2595, 6282, 2597, 5258, 2598, 3210, 2601, 4746, 2602, 2698, + 2609, 4490, 2627, 6218, 2629, 5194, 2630, 3146, 2633, 4682, + 2641, 4426, 2657, 4298, 2691, 6186, 2693, 5162, 2694, 3114, + 2697, 4650, 2705, 4394, 2721, 4266, 2753, 4202, 2819, 6170, + 2821, 5146, 2822, 3098, 2825, 4634, 2833, 4378, 2849, 4250, + 2881, 4186, 2945, 4154, 3079, 7174, 3083, 6662, 3085, 5638, + 3086, 3590, 3091, 6406, 3093, 5382, 3094, 3334, 3097, 4870, + 3107, 6278, 3109, 5254, 3110, 3206, 3113, 4742, 3121, 4486, + 3139, 6214, 3141, 5190, 3145, 4678, 3153, 4422, 3169, 4294, + 3203, 6182, 3205, 5158, 3209, 4646, 3217, 4390, 3233, 4262, + 3265, 4198, 3331, 6166, 3333, 5142, 3337, 4630, 3345, 4374, + 3361, 4246, 3393, 4182, 3457, 4150, 3587, 6158, 3589, 5134, + 3593, 4622, 3601, 4366, 3617, 4238, 3649, 4174, 3713, 4142, + 3841, 4126, 4111, 7681, 4119, 7425, 4123, 6913, 4125, 5889, + 4135, 7297, 4139, 6785, 4141, 5761, 4147, 6529, 4149, 5505, + 4153, 4993, 4167, 7233, 4171, 6721, 4173, 5697, 4179, 6465, + 4181, 5441, 4185, 4929, 4195, 6337, 4197, 5313, 4201, 4801, + 4209, 4545, 4231, 7201, 4235, 6689, 4237, 5665, 4243, 6433, + 4245, 5409, 4249, 4897, 4259, 6305, 4261, 5281, 4265, 4769, + 4273, 4513, 4291, 6241, 4293, 5217, 4297, 4705, 4305, 4449, + 4359, 7185, 4363, 6673, 4365, 5649, 4371, 6417, 4373, 5393, + 4377, 4881, 4387, 6289, 4389, 5265, 4393, 4753, 4401, 4497, + 4419, 6225, 4421, 5201, 4425, 4689, 4483, 6193, 4485, 5169, + 4489, 4657, 4615, 7177, 4619, 6665, 4621, 5641, 4627, 6409, + 4629, 5385, 4633, 4873, 4643, 6281, 4645, 5257, 4649, 4745, + 4675, 6217, 4677, 5193, 4739, 6185, 4741, 5161, 4867, 6169, + 4869, 5145, 5127, 7173, 5131, 6661, 5133, 5637, 5139, 6405, + 5141, 5381, 5155, 6277, 5157, 5253, 5187, 6213, 5251, 6181, + 5379, 6165, 5635, 6157, 6151, 7171, 6155, 6659, 6163, 6403, + 6179, 6275, 6211, 5189, 4681, 4433, 4321, 3142, 2634, 2386, + 2274, 1612, 1364, 1252, 856, 744, 496, + /* Table II 2 of 13. */ + 3, 6144, 5, 5120, 6, 3072, 9, 4608, 10, 2560, + 12, 1536, 17, 4352, 18, 2304, 20, 1280, 24, 768, + 33, 4224, 34, 2176, 36, 1152, 40, 640, 48, 384, + 65, 4160, 66, 2112, 68, 1088, 72, 576, 80, 320, + 96, 192, 129, 4128, 130, 2080, 132, 1056, 136, 544, + 144, 288, 257, 4112, 258, 2064, 260, 1040, 264, 528, + 513, 4104, 514, 2056, 516, 1032, 1025, 4100, 1026, 2052, + 2049, 4098, 4097, 2050, 1028, 520, 272, 160 + }; + + + /* + * Simple 104-bit integer type used during encoding + */ + class Int104 + { + public: + Int104( void ) + { + for ( int i = 0; i < 13; i++ ) + { + mByteArray[i] = 0; + } + } + + void multUint( uint32_t y ) + { + uint64_t carry = 0; + for ( int i = 12; i >= 0; i-- ) + { + uint64_t temp = mByteArray[i]*y + carry; + + mByteArray[i] = (uint8_t)(temp & 0xFF); + carry = temp >> 8; + } + } + + void addUint64( uint64_t y ) + { + uint64_t carry = 0; + for ( int i = 12; i >= 0; i-- ) + { + uint64_t temp = mByteArray[i] + (y&0xFF) + carry; + + mByteArray[i] = (uint8_t)(temp & 0xFF); + carry = temp >> 8; + y = y >> 8; + } + } + + uint32_t divUint( uint32_t y ) + { + uint32_t carry = 0; + for ( int i = 0; i < 13; i++ ) + { + uint32_t temp = mByteArray[i] + (carry << 8); + + mByteArray[i] = (uint8_t)(temp / y); + carry = temp % y; + } + return carry; + } + + uint8_t mByteArray[13]; + }; + +} + + +namespace glbarcode +{ + + /* + * Static Onecode barcode creation method + */ + Barcode* BarcodeOnecode::create( void ) + { + return new BarcodeOnecode(); + } + + + /* + * Onecode data validation, implements Barcode1dBase::validate() + */ + bool BarcodeOnecode::validate( const std::string& rawData ) + { + if ( (rawData.size() != 20) && + (rawData.size() != 25) && + (rawData.size() != 29) && + (rawData.size() != 31) ) + { + return false; + } + + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + if ( !isdigit( rawData[i] ) ) + { + return false; + } + } + + if (rawData[1] > '4') + { + return false; /* Invalid Barcode Identifier. */ + } + + return true; + } + + + /* + * Onecode data encoding, implements Barcode1dBase::encode() + */ + std::string BarcodeOnecode::encode( const std::string& cookedData ) + { + Int104 value; + + /*-----------------------------------------------------------*/ + /* Step 1 -- Conversion of Data Fields into Binary Data */ + /*-----------------------------------------------------------*/ + + /* Step 1.a -- Routing Code */ + int j; + for ( j = 20; cookedData[j] != 0; j++ ) + { + value.multUint( 10 ); + value.addUint64( cookedData[j] - '0' ); + } + switch ( j-20 ) + { + case 0: + break; + case 5: + value.addUint64( 1 ); + break; + case 9: + value.addUint64( 1 ); + value.addUint64( 100000 ); + break; + case 11: + value.addUint64( 1 ); + value.addUint64( 100000 ); + value.addUint64( 1000000000 ); + break; + default: + // Not reached + break; + } + + /* Step 1.b -- Tracking Code */ + value.multUint( 10 ); + value.addUint64( cookedData[0] - '0' ); + value.multUint( 5 ); + value.addUint64( cookedData[1] - '0' ); + + for ( int i = 2; i < 20; i++ ) + { + value.multUint( 10 ); + value.addUint64( cookedData[i] - '0' ); + } + + + /*-----------------------------------------------------------*/ + /* Step 2 -- Generation of 11-Bit CRC on Binary Data */ + /*-----------------------------------------------------------*/ + + unsigned int crc11 = USPS_MSB_Math_CRC11GenerateFrameCheckSequence( value.mByteArray ); + + + /*-----------------------------------------------------------*/ + /* Step 3 -- Conversion of Binary Data to Codewords */ + /*-----------------------------------------------------------*/ + unsigned int codeword[10]; + + codeword[9] = value.divUint( 636 ); + for ( int i = 8; i >= 1; i-- ) + { + codeword[i] = value.divUint( 1365 ); + } + codeword[0] = value.divUint( 659 ); + + + /*-----------------------------------------------------------*/ + /* Step 4 -- Inserting Additional Information into Codewords */ + /*-----------------------------------------------------------*/ + + codeword[9] *= 2; + codeword[0] += ((crc11 & 0x400) != 0) ? 659 : 0; + + + /*-----------------------------------------------------------*/ + /* Step 5 -- Conversion from Codewords to Characters */ + /*-----------------------------------------------------------*/ + unsigned int character[10]; + + for ( int i = 0; i < 10; i++ ) + { + character[i] = characterTable[ codeword[i] ]; + + if ( (crc11 & (1< + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeOnecode_h +#define glbarcode_BarcodeOnecode_h + + +#include "Barcode1dBase.h" + +#include + + +namespace glbarcode +{ + + /** + * @class BarcodeOnecode BarcodeOnecode.h glbarcode/BarcodeOnecode.h + * + * Onecode barcode, implements Barcode1dBase + * + * @image html sample-onecode.svg "Sample USPS Onecode Barcode" + * + */ + class BarcodeOnecode : public Barcode1dBase + { + public: + /** + * Static Onecode barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validate( const std::string& rawData ); + + std::string encode( const std::string& cookedData ); + + void vectorize( const std::string& codedData, + const std::string& displayText, + const std::string& cookedData, + double& w, + double& h ); + + + private: + uint32_t USPS_MSB_Math_CRC11GenerateFrameCheckSequence( const uint8_t* ByteArrayPtr ); + + }; + +} + + +#endif // glbarcode_BarcodeOnecode_h diff --git a/glbarcode/BarcodePostnet.cpp b/glbarcode/BarcodePostnet.cpp new file mode 100644 index 0000000..6f04eb7 --- /dev/null +++ b/glbarcode/BarcodePostnet.cpp @@ -0,0 +1,185 @@ +/* BarcodePostnet.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodePostnet.h" + +#include "Constants.h" + +#include +#include + + +using namespace glbarcode::Constants; + + +namespace +{ + /* + * Encoding symbology + */ + const std::string symbols[] = { + /* 0 */ "11000", + /* 1 */ "00011", + /* 2 */ "00101", + /* 3 */ "00110", + /* 4 */ "01001", + /* 5 */ "01010", + /* 6 */ "01100", + /* 7 */ "10001", + /* 8 */ "10010", + /* 9 */ "10100" + }; + + const std::string frameSymbol = "1"; + + + /* + * Constants + */ + const double POSTNET_BAR_WIDTH = ( 0.02 * PTS_PER_INCH ); + const double POSTNET_FULLBAR_HEIGHT = ( 0.125 * PTS_PER_INCH ); + const double POSTNET_HALFBAR_HEIGHT = ( 0.05 * PTS_PER_INCH ); + const double POSTNET_BAR_PITCH = ( 0.04545 * PTS_PER_INCH ); + const double POSTNET_HORIZ_MARGIN = ( 0.125 * PTS_PER_INCH ); + const double POSTNET_VERT_MARGIN = ( 0.04 * PTS_PER_INCH ); + +} + + +namespace glbarcode +{ + + /* + * Static Postnet barcode creation method + */ + Barcode* BarcodePostnet::create( void ) + { + return new BarcodePostnet(); + } + + + /* + * Postnet validate number of digits + */ + bool BarcodePostnet::validateDigits( int nDigits ) + { + /* Accept any valid USPS POSTNET length. */ + return (nDigits == 5) || (nDigits == 9) || (nDigits == 11); + } + + + /* + * Postnet data validation, implements Barcode1dBase::validate() + */ + bool BarcodePostnet::validate( const std::string& rawData ) + { + int nDigits = 0; + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + if ( isdigit( rawData[i] ) ) + { + nDigits++; + } + else if ( (rawData[i] != '-') && (rawData[i] != ' ') ) + { + /* Only allow digits, dashes, and spaces. */ + return false; + } + } + + return validateDigits( nDigits ); + } + + + /* + * Postnet data encoding, implements Barcode1dBase::encode() + */ + std::string BarcodePostnet::encode( const std::string& cookedData ) + { + std::string code; + + /* Left frame bar */ + code += frameSymbol; + + /* process each digit, adding approptiate symbol */ + int sum = 0; + for ( unsigned int i = 0; i < cookedData.size(); i++ ) + { + if ( isdigit( cookedData[i] ) ) + { + /* Only translate the digits (0-9) */ + int d = cookedData[i] - '0'; + code += symbols[d]; + sum += d; + } + } + + /* Create mandatory correction character */ + code += symbols[ (10 - (sum % 10)) % 10 ]; + + /* Right frame bar */ + code += frameSymbol; + + return code; + } + + + /* + * Postnet vectorization, implements Barcode1dBase::vectorize() + */ + void BarcodePostnet::vectorize( const std::string& codedData, + const std::string& displayText, + const std::string& cookedData, + double& w, + double& h ) + { + double x = POSTNET_HORIZ_MARGIN; + for ( unsigned int i=0; i < codedData.size(); i++ ) + { + double length, width; + + double y = POSTNET_VERT_MARGIN; + + switch ( codedData[i] ) + { + case '0': + y += POSTNET_FULLBAR_HEIGHT - POSTNET_HALFBAR_HEIGHT; + length = POSTNET_HALFBAR_HEIGHT; + break; + case '1': + length = POSTNET_FULLBAR_HEIGHT; + break; + default: + // Not reached + break; + } + width = POSTNET_BAR_WIDTH; + + addLine( x, y, width, length ); + + x += POSTNET_BAR_PITCH; + } + + /* Overwrite requested size with actual size. */ + w = x + POSTNET_HORIZ_MARGIN; + h = POSTNET_FULLBAR_HEIGHT + 2 * POSTNET_VERT_MARGIN; + } + +} diff --git a/glbarcode/BarcodePostnet.h b/glbarcode/BarcodePostnet.h new file mode 100644 index 0000000..b21f8d8 --- /dev/null +++ b/glbarcode/BarcodePostnet.h @@ -0,0 +1,98 @@ +/* BarcodePostnet.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodePostnet_h +#define glbarcode_BarcodePostnet_h + + +#include "Barcode1dBase.h" + + +namespace glbarcode +{ + + /** + * @class BarcodePostnet BarcodePostnet.h glbarcode/BarcodePostnet.h + * + * *POSTNET* barcode (All USPS sizes: ZIP, ZIP+4, ZIP+4+DC). + * + * @image html sample-postnet.svg "Sample USPS POSTNET Barcode" + * + * + * ### Input Data Format ### + * + * The *POSTNET* specification defines 10 characters, consisting solely + * of decimal digits (0-9). The BarcodePostnet validator and encoder will + * ignore spaces and dashes (-). The validator will only accept input + * data with 5 digits (ZIP), 9 digits (ZIP+4) or 11 digits (ZIP+4+DC). + * + * + * ### Checksum Property ### + * + * The *checksum* property is ignored. A mandatory check digit will + * always be automatically generated and appended to the input data + * prior to encoding. + * + * + * ### Show Text Property ### + * + * The *Show Text* property is ignored. + * + * + * ### References ### + * + * - http://en.wikipedia.org/wiki/POSTNET + * + */ + class BarcodePostnet : public Barcode1dBase + { + public: + /** + * Static Postnet barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + protected: + /** + * Validate number of digits + */ + virtual bool validateDigits( int nDigits ); + + + private: + bool validate( const std::string& rawData ); + + std::string encode( const std::string& cookedData ); + + void vectorize( const std::string& codedData, + const std::string& displayText, + const std::string& cookedData, + double& w, + double& h ); + + }; + +} + + +#endif // glbarcode_BarcodePostnet_h diff --git a/glbarcode/BarcodePostnet11.cpp b/glbarcode/BarcodePostnet11.cpp new file mode 100644 index 0000000..7329323 --- /dev/null +++ b/glbarcode/BarcodePostnet11.cpp @@ -0,0 +1,44 @@ +/* BarcodePostnet11.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodePostnet11.h" + + +namespace glbarcode +{ + + /* + * Static Postnet-11 barcode creation method + */ + Barcode* BarcodePostnet11::create( void ) + { + return new BarcodePostnet11(); + } + + + /* + * Postnet-11 validation of number of digits, overrides BarcodePostnet::validateDigits() + */ + bool BarcodePostnet11::validateDigits( int nDigits ) + { + return nDigits == 11; /* Zip + 4 + Delivery Code */ + } + +} diff --git a/glbarcode/BarcodePostnet11.h b/glbarcode/BarcodePostnet11.h new file mode 100644 index 0000000..2400731 --- /dev/null +++ b/glbarcode/BarcodePostnet11.h @@ -0,0 +1,66 @@ +/* BarcodePostnet11.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodePostnet11_h +#define glbarcode_BarcodePostnet11_h + + +#include "BarcodePostnet.h" + + +namespace glbarcode +{ + + /** + * @class BarcodePostnet11 BarcodePostnet11.h glbarcode/BarcodePostnet11.h + * + * *POSTNET-11* barcode (ZIP only), extends BarcodePostnet + * + * @image html sample-postnet-11.svg "Sample 11 digit USPS POSTNET Barcode" + * + * + * ### Input Data Format ### + * + * Input data requirements are identical to BarcodePostnet, except the + * validator only accepts 11 digits (ZIP+4+DC) of input. + * + * See BarcodePostnet. + * + */ + class BarcodePostnet11 : public BarcodePostnet + { + public: + /** + * Static POSTNET-11 barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validateDigits( int nDigits ); + + }; + +} + + +#endif // glbarcode_BarcodePostnet11_h diff --git a/glbarcode/BarcodePostnet5.cpp b/glbarcode/BarcodePostnet5.cpp new file mode 100644 index 0000000..d48df18 --- /dev/null +++ b/glbarcode/BarcodePostnet5.cpp @@ -0,0 +1,44 @@ +/* BarcodePostnet5.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodePostnet5.h" + + +namespace glbarcode +{ + + /* + * Static Postnet-5 barcode creation method + */ + Barcode* BarcodePostnet5::create( void ) + { + return new BarcodePostnet5(); + } + + + /* + * Postnet-5 validation of number of digits, overrides BarcodePostnet::validateDigits() + */ + bool BarcodePostnet5::validateDigits( int nDigits ) + { + return nDigits == 5; /* Zip only */ + } + +} diff --git a/glbarcode/BarcodePostnet5.h b/glbarcode/BarcodePostnet5.h new file mode 100644 index 0000000..fab419a --- /dev/null +++ b/glbarcode/BarcodePostnet5.h @@ -0,0 +1,66 @@ +/* BarcodePostnet5.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodePostnet5_h +#define glbarcode_BarcodePostnet5_h + + +#include "BarcodePostnet.h" + + +namespace glbarcode +{ + + /** + * @class BarcodePostnet5 BarcodePostnet5.h glbarcode/BarcodePostnet5.h + * + * *POSTNET-5* barcode (ZIP only), extends BarcodePostnet + * + * @image html sample-postnet-5.svg "Sample 5 digit USPS POSTNET Barcode" + * + * + * ### Input Data Format ### + * + * Input data requirements are identical to BarcodePostnet, except the + * validator only accepts 5 digits (ZIP) of input. + * + * See BarcodePostnet. + * + */ + class BarcodePostnet5 : public BarcodePostnet + { + public: + /** + * Static POSTNET-5 barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validateDigits( int nDigits ); + + }; + +} + + +#endif // glbarcode_BarcodePostnet5_h diff --git a/glbarcode/BarcodePostnet9.cpp b/glbarcode/BarcodePostnet9.cpp new file mode 100644 index 0000000..87d9fc2 --- /dev/null +++ b/glbarcode/BarcodePostnet9.cpp @@ -0,0 +1,44 @@ +/* BarcodePostnet9.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodePostnet9.h" + + +namespace glbarcode +{ + + /* + * Static Postnet-9 barcode creation method + */ + Barcode* BarcodePostnet9::create( void ) + { + return new BarcodePostnet9(); + } + + + /* + * Postnet-9 validation of number of digits, overrides BarcodePostnet::validateDigits() + */ + bool BarcodePostnet9::validateDigits( int nDigits ) + { + return nDigits == 9; /* Zip + 4 */ + } + +} diff --git a/glbarcode/BarcodePostnet9.h b/glbarcode/BarcodePostnet9.h new file mode 100644 index 0000000..cea2479 --- /dev/null +++ b/glbarcode/BarcodePostnet9.h @@ -0,0 +1,66 @@ +/* BarcodePostnet9.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodePostnet9_h +#define glbarcode_BarcodePostnet9_h + + +#include "BarcodePostnet.h" + + +namespace glbarcode +{ + + /** + * @class BarcodePostnet9 BarcodePostnet9.h glbarcode/BarcodePostnet9.h + * + * *POSTNET-9* barcode (ZIP+4 only), extends BarcodePostnet + * + * @image html sample-postnet-9.svg "Sample 9 digit USPS POSTNET Barcode" + * + * + * ### Input Data Format ### + * + * Input data requirements are identical to BarcodePostnet, except the + * validator only accepts 9 digits (ZIP+4) of input. + * + * See BarcodePostnet. + * + */ + class BarcodePostnet9 : public BarcodePostnet + { + public: + /** + * Static POSTNET-9 barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validateDigits( int nDigits ); + + }; + +} + + +#endif // glbarcode_BarcodePostnet9_h diff --git a/glbarcode/BarcodeQrcode.cpp b/glbarcode/BarcodeQrcode.cpp new file mode 100644 index 0000000..e2f3ff6 --- /dev/null +++ b/glbarcode/BarcodeQrcode.cpp @@ -0,0 +1,87 @@ +/* BarcodeQrcode.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#if HAVE_QRENCODE + +#include "BarcodeQrcode.h" + +#include "qrencode.h" + + +namespace glbarcode +{ + + /* + * Static Qrcode barcode creation method + */ + Barcode* BarcodeQrcode::create( void ) + { + return new BarcodeQrcode(); + } + + + /* + * Qrcode data validation, implements Barcode2dBase::validate() + */ + bool BarcodeQrcode::validate( const std::string& rawData ) + { + if ( rawData.size() == 0 ) + { + return false; + } + return true; + } + + + /* + * Qrcode data encoding, implements Barcode2dBase::encode() + */ + bool BarcodeQrcode::encode( const std::string& cookedData, Matrix& encodedData ) + { + QRcode *qrcode = QRcode_encodeString( cookedData.c_str(), 0, QR_ECLEVEL_M, QR_MODE_8, 1 ); + if ( qrcode == NULL ) + { + return false; + } + + + int w = qrcode->width; + encodedData.resize( w, w ); + + + for ( int iy = 0; iy < w; iy++ ) + { + for ( int ix = 0; ix < w; ix++ ) + { + encodedData[iy][ix] = qrcode->data[ iy*w + ix ] & 0x01; + } + } + + + QRcode_free( qrcode ); + QRcode_clearCache(); + + return true; + } + + +} + +#endif // HAVE_QRENCODE diff --git a/glbarcode/BarcodeQrcode.h b/glbarcode/BarcodeQrcode.h new file mode 100644 index 0000000..07367b8 --- /dev/null +++ b/glbarcode/BarcodeQrcode.h @@ -0,0 +1,59 @@ +/* BarcodeQrcode.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeQrcode_h +#define glbarcode_BarcodeQrcode_h + + +#include "Barcode2dBase.h" + + +namespace glbarcode +{ + + /** + * @class BarcodeQrcode BarcodeQrcode.h glbarcode/BarcodeQrcode.h + * + * QRCode barcode, implements Barcode2dBase. + * + * @image html sample-qrcode.svg "Sample QRCode Barcode" + */ + class BarcodeQrcode : public Barcode2dBase + { + public: + /** + * Static QRCode barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + private: + bool validate( const std::string& rawData ); + + bool encode( const std::string& cookedData, + Matrix& encodedData ); + + }; + +} + +#endif // glbarcode_BarcodeQrcode_h diff --git a/glbarcode/BarcodeUpcA.cpp b/glbarcode/BarcodeUpcA.cpp new file mode 100644 index 0000000..e99d79c --- /dev/null +++ b/glbarcode/BarcodeUpcA.cpp @@ -0,0 +1,96 @@ +/* BarcodeUpcA.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodeUpcA.h" + +#include +#include + + +namespace glbarcode +{ + + /* + * Static UPC-A barcode creation method + */ + Barcode* BarcodeUpcA::create( void ) + { + return new BarcodeUpcA(); + } + + + /* + * UPC-A barcode constructor + */ + BarcodeUpcA::BarcodeUpcA() + { + mEndBarsModules = 7; + } + + + /* + * UPC-A validate number of digits, implements BarcodeUpcBase::validateDigits() + */ + bool BarcodeUpcA::validateDigits( int nDigits ) + { + return (nDigits == 11); + } + + + /* + * UPC-A Pre-process data before encoding, implements Barcode1dBase::preprocess() + */ + std::string BarcodeUpcA::preprocess( const std::string& rawData ) + { + std::string cookedData; + + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + if ( isdigit( rawData[i] ) ) + { + cookedData += rawData[i]; + } + } + + mFirstDigitVal = 0; + return cookedData; + } + + + /* + * UPC-A vectorize text, implements BarcodeUpcBase::vectorizeText() + */ + void BarcodeUpcA::vectorizeText( const std::string& displayText, + double size1, + double size2, + double x1Left, + double x1Right, + double y1, + double x2Left, + double x2Right, + double y2 ) + { + addText( x2Left, y2, size2, displayText.substr( 0, 1 ) ); + addText( x1Left, y1, size1, displayText.substr( 1, 5 ) ); + addText( x1Right, y1, size1, displayText.substr( 6, 5 ) ); + addText( x2Right, y2, size2, displayText.substr( 11, 1 ) ); + } + +} diff --git a/glbarcode/BarcodeUpcA.h b/glbarcode/BarcodeUpcA.h new file mode 100644 index 0000000..c3579bd --- /dev/null +++ b/glbarcode/BarcodeUpcA.h @@ -0,0 +1,76 @@ +/* BarcodeUpcA.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeUpcA_h +#define glbarcode_BarcodeUpcA_h + + +#include "BarcodeUpcBase.h" + + +namespace glbarcode +{ + + /** + * @class BarcodeUpcA BarcodeUpcA.h glbarcode/BarcodeUpcA.h + * + * UPC-A barcode, implements BarcodeUpcBase + * + * @image html sample-upc-a.svg "Sample UPC-A Barcode" + * + */ + class BarcodeUpcA : public BarcodeUpcBase + { + public: + /** + * Static UPC-A barcode creation method + * + * Used by glbarcode::BarcodeFactory + */ + static Barcode* create( void ); + + + /** + * Default constructor + */ + BarcodeUpcA(); + + + private: + bool validateDigits( int nDigits ); + + std::string preprocess( const std::string& rawData ); + + void vectorizeText( const std::string& displayText, + double size1, + double size2, + double x1Left, + double x1Right, + double y1, + double x2Left, + double x2Right, + double y2 ); + + }; + +} + + +#endif // glbarcode_BarcodeUpcA_h diff --git a/glbarcode/BarcodeUpcBase.cpp b/glbarcode/BarcodeUpcBase.cpp new file mode 100644 index 0000000..440ddf8 --- /dev/null +++ b/glbarcode/BarcodeUpcBase.cpp @@ -0,0 +1,297 @@ +/* BarcodeUpcBase.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "BarcodeUpcBase.h" + +#include "Constants.h" + +#include +#include +#include +#include + + +using namespace glbarcode::Constants; + + +namespace +{ + /* + * Symbology + */ + const std::string symbols[10][2] = { + /* Odd Even */ + /* Left: sBsB sBsB */ + /* Right: BsBs ---- */ + /* */ + /* 0 */ { "3211", "1123" }, + /* 1 */ { "2221", "1222" }, + /* 2 */ { "2122", "2212" }, + /* 3 */ { "1411", "1141" }, + /* 4 */ { "1132", "2311" }, + /* 5 */ { "1231", "1321" }, + /* 6 */ { "1114", "4111" }, + /* 7 */ { "1312", "2131" }, + /* 8 */ { "1213", "3121" }, + /* 9 */ { "3112", "2113" } + }; + + const std::string sSymbol = "111"; /* BsB */ + const std::string eSymbol = "111"; /* BsB */ + const std::string mSymbol = "11111"; /* sBsBs */ + + + /* + * Parity selection + */ + typedef enum { P_ODD, P_EVEN } Parity; + + const Parity parity[10][6] = { + /* Pos 1, Pos 2, Pos 3, Pos 4, Pos 5, Pos 6 */ + /* 0 (UPC-A) */ { P_ODD, P_ODD, P_ODD, P_ODD, P_ODD, P_ODD }, + /* 1 */ { P_ODD, P_ODD, P_EVEN, P_ODD, P_EVEN, P_EVEN }, + /* 2 */ { P_ODD, P_ODD, P_EVEN, P_EVEN, P_ODD, P_EVEN }, + /* 3 */ { P_ODD, P_ODD, P_EVEN, P_EVEN, P_EVEN, P_ODD }, + /* 4 */ { P_ODD, P_EVEN, P_ODD, P_ODD, P_EVEN, P_EVEN }, + /* 5 */ { P_ODD, P_EVEN, P_EVEN, P_ODD, P_ODD, P_EVEN }, + /* 6 */ { P_ODD, P_EVEN, P_EVEN, P_EVEN, P_ODD, P_ODD }, + /* 7 */ { P_ODD, P_EVEN, P_ODD, P_EVEN, P_ODD, P_EVEN }, + /* 8 */ { P_ODD, P_EVEN, P_ODD, P_EVEN, P_EVEN, P_ODD }, + /* 9 */ { P_ODD, P_EVEN, P_EVEN, P_ODD, P_EVEN, P_ODD } + }; + + + /* + * Constants + */ + const int QUIET_MODULES = 9; + + const double BASE_MODULE_SIZE = ( 0.01 * PTS_PER_INCH ); + const double BASE_FONT_SIZE = 7; + const double BASE_TEXT_AREA_HEIGHT = 11; +} + + +namespace glbarcode +{ + + /* + * UPC data validation, implements Barcode1dBase::validate() + */ + bool BarcodeUpcBase::validate( const std::string& rawData ) + { + int nDigits = 0; + + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + if ( isdigit( rawData[i] ) ) + { + nDigits++; + } + else if ( rawData[i] != ' ') + { + /* Only allow digits and spaces -- ignoring spaces. */ + return false; + } + } + + /* validate nDigits (call implementation from concrete class) */ + return validateDigits( nDigits ); + } + + + /* + * UPC data encoding, implements Barcode1dBase::encode() + */ + std::string BarcodeUpcBase::encode( const std::string& cookedData ) + { + int sumOdd = 0; + int sumEven = mFirstDigitVal; + + std::string code; + + /* Left frame symbol */ + code += sSymbol; + + /* Left 6 digits */ + for ( int i = 0; i < 6; i++ ) + { + int cValue = cookedData[i] - '0'; + code += symbols[ cValue ][ parity[ mFirstDigitVal ][ i ] ]; + + if ( (i & 1) == 0 ) + { + sumOdd += cValue; + } + else + { + sumEven += cValue; + } + } + + /* Middle frame symbol */ + code += mSymbol; + + /* Right 5 digits */ + for ( int i = 6; i < 11; i++ ) + { + int cValue = cookedData[i] - '0'; + code += symbols[cValue][P_ODD]; + + if ( (i & 1) == 0 ) + { + sumOdd += cValue; + } + else + { + sumEven += cValue; + } + } + + /* Check digit */ + mCheckDigitVal = (3*sumOdd + sumEven) % 10; + if ( mCheckDigitVal != 0 ) + { + mCheckDigitVal = 10 - mCheckDigitVal; + } + code += symbols[mCheckDigitVal][P_ODD]; + + /* Right frame symbol */ + code += eSymbol; + + /* Append a final zero length space to make the length of the encoded string even. */ + /* This is because vectorize() handles bars and spaces in pairs. */ + code += "0"; + + return code; + } + + + + /* + * UPC prepare text for display, implements Barcode1dBase::prepareText() + */ + std::string BarcodeUpcBase::prepareText( const std::string& rawData ) + { + std::string displayText; + + for ( unsigned int i = 0; i < rawData.size(); i++ ) + { + if ( isdigit( rawData[i] ) ) + { + displayText += rawData[i]; + } + } + + displayText += (mCheckDigitVal + '0'); + + return displayText; + } + + + /* + * UPC vectorization, implements Barcode1dBase::vectorize() + */ + void BarcodeUpcBase::vectorize( const std::string& codedData, + const std::string& displayText, + const std::string& cookedData, + double& w, + double& h ) + { + /* determine width and establish horizontal scale */ + int nModules = 7*(cookedData.size()+1) + 11; + + double scale; + if ( w == 0 ) + { + scale = 1.0; + } + else + { + scale = w / ((nModules + 2*QUIET_MODULES) * BASE_MODULE_SIZE); + + if ( scale < 1.0 ) + { + scale = 1.0; + } + } + double mscale = scale * BASE_MODULE_SIZE; + + double width = mscale * (nModules + 2*QUIET_MODULES); + double xQuiet = mscale * QUIET_MODULES; + + /* determine bar height */ + double hTextArea = scale * BASE_TEXT_AREA_HEIGHT; + double hBar1 = std::max( (h - hTextArea), width/2 ); + double hBar2 = hBar1 + hTextArea/2; + + /* determine text parameters */ + double textSize1 = scale * BASE_FONT_SIZE; + double textSize2 = 0.75*textSize1; + + double textX1Left = xQuiet + mscale*(0.25*nModules + 0.5*mEndBarsModules - 0.75); + double textX1Right = xQuiet + mscale*(0.75*nModules - 0.5*mEndBarsModules + 0.75); + double textX2Left = 0.5*xQuiet; + double textX2Right = 1.5*xQuiet + mscale*nModules; + + double textY1 = hBar2 + textSize1/4; + double textY2 = hBar2 + textSize2/4; + + + /* now traverse the code string and draw each bar */ + int nBarsSpaces = codedData.size() - 1; /* coded data has dummy "0" on end. */ + + double xModules = 0; + for ( int i = 0; i < nBarsSpaces; i += 2 ) + { + double hBar; + + if ( ( (xModules > mEndBarsModules) && (xModules < (nModules/2-1)) ) || + ( (xModules > (nModules/2+1)) && (xModules < (nModules-mEndBarsModules)) ) ) + { + hBar = hBar1; + } + else + { + hBar = hBar2; + } + + /* Bar */ + int wBar = codedData[i] - '0'; + addLine( xQuiet + mscale*xModules, 0.0, mscale*wBar, hBar ); + xModules += wBar; + + /* Space */ + int wSpace = codedData[i+1] - '0'; + xModules += wSpace; + } + + /* draw text (call implementation from concrete class) */ + vectorizeText( displayText, + textSize1, textSize2, + textX1Left, textX1Right, textY1, + textX2Left, textX2Right, textY2 ); + + /* Overwrite requested size with actual size. */ + w = width; + h = hBar1 + hTextArea; + } + +} diff --git a/glbarcode/BarcodeUpcBase.h b/glbarcode/BarcodeUpcBase.h new file mode 100644 index 0000000..8ea0bdc --- /dev/null +++ b/glbarcode/BarcodeUpcBase.h @@ -0,0 +1,78 @@ +/* BarcodeUpcBase.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_BarcodeUpcBase_h +#define glbarcode_BarcodeUpcBase_h + + +#include "Barcode1dBase.h" + + +namespace glbarcode +{ + + /** + * @class BarcodeUpcBase BarcodeUpcBase.h glbarcode/BarcodeUpcBase.h + * + * UpcBase barcode, base class for UPC-A and EAN-13 barcode types, implements Barcode1dBase + */ + class BarcodeUpcBase : public Barcode1dBase + { + protected: + virtual bool validateDigits( int nDigits ) = 0; + + virtual void vectorizeText( const std::string& displayText, + double size1, + double size2, + double x1Left, + double x1Right, + double y1, + double x2Left, + double x2Right, + double y2 ) = 0; + + private: + bool validate( const std::string& rawData ); + + std::string encode( const std::string& cookedData ); + + std::string prepareText( const std::string& rawData ); + + void vectorize( const std::string& codedData, + const std::string& displayText, + const std::string& cookedData, + double& w, + double& h ); + + + protected: + int mEndBarsModules; + int mFirstDigitVal; + + + private: + int mCheckDigitVal; + + }; + +} + + +#endif // glbarcode_BarcodeUpcBase_h diff --git a/glbarcode/CMakeLists.txt b/glbarcode/CMakeLists.txt new file mode 100644 index 0000000..f08a946 --- /dev/null +++ b/glbarcode/CMakeLists.txt @@ -0,0 +1,52 @@ +#======================================= +# Compilation +#======================================= +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +add_compile_options (-std=c++11 -g) +if (NOT WIN32) + add_compile_options (-fPIC) +endif () + +# Uncomment to build with pedantic flags +#add_compile_options (-Werror -Wall -Wpedantic) + + +#======================================= +# Sources +#======================================= +set (LIB_SOURCES + Factory.cpp + Barcode.cpp + Barcode1dBase.cpp + Barcode2dBase.cpp + BarcodeCode39.cpp + BarcodeCode39Ext.cpp + BarcodeUpcBase.cpp + BarcodeUpcA.cpp + BarcodeEan13.cpp + BarcodePostnet.cpp + BarcodePostnet5.cpp + BarcodePostnet9.cpp + BarcodePostnet11.cpp + BarcodeCepnet.cpp + BarcodeOnecode.cpp + BarcodeDataMatrix.cpp + BarcodeQrcode.cpp + DrawingPrimitives.cpp + Renderer.cpp + QtRenderer.cpp +) + +add_library (glbarcode + ${LIB_SOURCES} +) + + +#======================================= +# Where to find stuff +#======================================= +include_directories ( + ${Qt5Widgets_INCLUDE_DIRS} +) + diff --git a/glbarcode/Constants.h b/glbarcode/Constants.h new file mode 100644 index 0000000..a9d8128 --- /dev/null +++ b/glbarcode/Constants.h @@ -0,0 +1,38 @@ +/* Constants.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_Constants_h +#define glbarcode_Constants_h + + +namespace glbarcode +{ + + namespace Constants + { + const double PTS_PER_INCH = 72.0; /**< Points per inch. */ + const double PTS_PER_MM = 2.83464566929; /**< Points per millimeter. */ + const double PTS_PER_CM = 10*PTS_PER_MM; /**< Points per centimeter. */ + } + +} + + +#endif // glbarcode_Constants_h diff --git a/glbarcode/DrawingPrimitives.cpp b/glbarcode/DrawingPrimitives.cpp new file mode 100644 index 0000000..463de23 --- /dev/null +++ b/glbarcode/DrawingPrimitives.cpp @@ -0,0 +1,138 @@ +/* DrawingPrimitives.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "DrawingPrimitives.h" + + +namespace glbarcode +{ + + DrawingPrimitive::DrawingPrimitive( double x, double y ) + : mX(x), mY(y) + { + } + + + DrawingPrimitive::~DrawingPrimitive() + { + } + + + double DrawingPrimitive::x() const + { + return mX; + } + + + double DrawingPrimitive::y() const + { + return mY; + } + + + + DrawingPrimitiveLine::DrawingPrimitiveLine( double x, double y, double w, double h ) + : DrawingPrimitive( x, y ), mW(w), mH(h) + { + } + + + double DrawingPrimitiveLine::w() const + { + return mW; + } + + + double DrawingPrimitiveLine::h() const + { + return mH; + } + + + + DrawingPrimitiveBox::DrawingPrimitiveBox( double x, double y, double w, double h ) + : DrawingPrimitive( x, y ), mW(w), mH(h) + { + } + + + double DrawingPrimitiveBox::w() const + { + return mW; + } + + + double DrawingPrimitiveBox::h() const + { + return mH; + } + + + + DrawingPrimitiveText::DrawingPrimitiveText( double x, double y, double size, const std::string& text ) + : DrawingPrimitive( x, y ), mSize(size), mText(text) + { + } + + + double DrawingPrimitiveText::size() const + { + return mSize; + } + + + const std::string& DrawingPrimitiveText::text() const + { + return mText; + } + + + + DrawingPrimitiveRing::DrawingPrimitiveRing( double x, double y, double r, double w ) + : DrawingPrimitive( x, y ), mR(r), mW(w) + { + } + + + double DrawingPrimitiveRing::r() const + { + return mR; + } + + + double DrawingPrimitiveRing::w() const + { + return mW; + } + + + + DrawingPrimitiveHexagon::DrawingPrimitiveHexagon( double x, double y, double h ) + : DrawingPrimitive( x, y ), mH(h) + { + } + + + double DrawingPrimitiveHexagon::h() const + { + return mH; + } + +} diff --git a/glbarcode/DrawingPrimitives.h b/glbarcode/DrawingPrimitives.h new file mode 100644 index 0000000..b510e95 --- /dev/null +++ b/glbarcode/DrawingPrimitives.h @@ -0,0 +1,254 @@ +/* DrawingPrimitives.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_DrawingPrimitives_h +#define glbarcode_DrawingPrimitives_h + + +#include + + +namespace glbarcode +{ + + /** + * @class DrawingPrimitive DrawingPrimitives.h glbarcode/DrawingPrimitives.h + * + * Base class for all drawing primitives + */ + class DrawingPrimitive + { + protected: + /** + * Constructor + * + * @param[in] x X coordinate of primitive's origin (points) + * @param[in] y Y coordinate of primitive's origin (points) + */ + DrawingPrimitive( double x, double y ); + + public: + /** + * Destructor + */ + virtual ~DrawingPrimitive(); + + /** + * Get X coordinate of primitive's origin (points). + */ + double x() const; + + /** + * Get Y coordinate of primitive's origin (points). + */ + double y() const; + + private: + double mX; /**< X coordinate of primitive's origin (points). */ + double mY; /**< Y coordinate of primitive's origin (points). */ + }; + + + + /** + * @class DrawingPrimitiveLine DrawingPrimitives.h glbarcode/DrawingPrimitives.h + * + * A solid vertical line drawing primitive. + * + * @image html figure-primitive-line.svg "Line primitive properties" + * + */ + class DrawingPrimitiveLine : public DrawingPrimitive + { + public: + /** + * Line constructor + * + * @param[in] x X coordinate of line's origin (points) + * @param[in] y Y coordinate of line's origin (points) + * @param[in] w Line width (points) + * @param[in] h Line height (points) + */ + DrawingPrimitiveLine( double x, double y, double w, double h ); + + /** + * Get line width (points). + */ + double w() const; + + /** + * Get line height (points). + */ + double h() const; + + private: + double mW; /**< Line width (points). */ + double mH; /**< Line length (points). */ + }; + + + + /** + * @class DrawingPrimitiveBox DrawingPrimitives.h glbarcode/DrawingPrimitives.h + * + * A solid box drawing primitive. + * + * @image html figure-primitive-box.svg "Box primitive properties" + * + */ + class DrawingPrimitiveBox : public DrawingPrimitive + { + public: + /** + * Box constructor + * + * @param[in] x X coordinate of box's origin (points) + * @param[in] y Y coordinate of box's origin (points) + * @param[in] w Width of box (points) + * @param[in] h Height of box (points) + */ + DrawingPrimitiveBox( double x, double y, double w, double h ); + + /** + * Get box width (points). + */ + double w() const; + + /** + * Get box height (points). + */ + double h() const; + + private: + double mW; /**< Width of box (points). */ + double mH; /**< Height of box (points). */ + }; + + + + /** + * @class DrawingPrimitiveText DrawingPrimitives.h glbarcode/DrawingPrimitives.h + * + * A character string drawing primitive. + * + * @image html figure-primitive-text.svg "Text primitive properties" + * + */ + class DrawingPrimitiveText : public DrawingPrimitive + { + public: + /** + * Text constructor + * + * @param[in] x X coordinate of text's origin (points) + * @param[in] y Y coordinate of text's origin (points) + * @param[in] size Font size of text (points) + * @param[in] text Text + */ + DrawingPrimitiveText( double x, double y, double size, const std::string& text ); + + /** + * Get font size (points). + */ + double size() const; + + /** + * Get text. + */ + const std::string& text() const; + + private: + double mSize; /**< Font size of text (points). */ + std::string mText; /**< Text. */ + }; + + + + /** + * @class DrawingPrimitiveRing DrawingPrimitives.h glbarcode/DrawingPrimitives.h + * + * A ring (an open circle) drawing primitive. + * + * @image html figure-primitive-ring.svg "Ring primitive properties" + * + */ + class DrawingPrimitiveRing : public DrawingPrimitive + { + public: + /** + * Ring constructor + * + * @param[in] x X coordinate of ring's origin (points) + * @param[in] y Y coordinate of ring's origin (points) + * @param[in] r Radius of ring (points) + * @param[in] w Line width of ring (points) + */ + DrawingPrimitiveRing( double x, double y, double r, double w ); + + /** + * Get radius of ring (points). + */ + double r() const; + + /** + * Get line width (points). + */ + double w() const; + + private: + double mR; /**< Radius of ring (points). */ + double mW; /**< Line width of ring (points). */ + }; + + + + /** + * @class DrawingPrimitiveHexagon DrawingPrimitives.h glbarcode/DrawingPrimitives.h + * + * A solid regular hexagon (oriented with vertexes at top and bottom) drawing primitive. + * + * @image html figure-primitive-hexagon.svg "Hexagon primitive properties" + * + */ + class DrawingPrimitiveHexagon : public DrawingPrimitive + { + public: + /** + * Hexagon constructor + * + * @param[in] x X coordinate of hexagon's origin (points) + * @param[in] y Y coordinate of hexagon's origin (points) + * @param[in] h Height of hexagon (points) + */ + DrawingPrimitiveHexagon( double x, double y, double h ); + + /** + * Get Hexagon height (points). + */ + double h() const; + + private: + double mH; /**< Height of hexagon (points). */ + }; + +} + + +#endif // glbarcode_DrawingPrimitives_h diff --git a/glbarcode/Factory.cpp b/glbarcode/Factory.cpp new file mode 100644 index 0000000..0830330 --- /dev/null +++ b/glbarcode/Factory.cpp @@ -0,0 +1,125 @@ +/* Factory.cpp + * + * Copyright (C) 2013-2014 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "Factory.h" + +#include "BarcodeCode39.h" +#include "BarcodeCode39Ext.h" +#include "BarcodeUpcA.h" +#include "BarcodeEan13.h" +#include "BarcodePostnet.h" +#include "BarcodePostnet5.h" +#include "BarcodePostnet9.h" +#include "BarcodePostnet11.h" +#include "BarcodeCepnet.h" +#include "BarcodeOnecode.h" +#include "BarcodeDataMatrix.h" +#include "BarcodeQrcode.h" + + +namespace glbarcode +{ + + Factory::BarcodeTypeMap Factory::mBarcodeTypeMap; + TypeIdList Factory::mSupportedTypes; + + + Factory::Factory() + { + /* + * Register built-in types. + */ + internalRegisterType( "code39", &BarcodeCode39::create ); + internalRegisterType( "code39ext", &BarcodeCode39Ext::create ); + internalRegisterType( "upc-a", &BarcodeUpcA::create ); + internalRegisterType( "ean-13", &BarcodeEan13::create ); + internalRegisterType( "postnet", &BarcodePostnet::create ); + internalRegisterType( "postnet-5", &BarcodePostnet5::create ); + internalRegisterType( "postnet-9", &BarcodePostnet9::create ); + internalRegisterType( "postnet-11", &BarcodePostnet11::create ); + internalRegisterType( "cepnet", &BarcodeCepnet::create ); + internalRegisterType( "onecode", &BarcodeOnecode::create ); + internalRegisterType( "datamatrix", &BarcodeDataMatrix::create ); +#if HAVE_QRENCODE + internalRegisterType( "qrcode", &BarcodeQrcode::create ); +#endif + } + + + void Factory::init( void ) + { + static Factory* singletonInstance = NULL; + + if ( singletonInstance == NULL ) + { + singletonInstance = new Factory(); + } + } + + + void Factory::registerType( const std::string& typeId, Factory::BarcodeCreateFct fct ) + { + init(); + + internalRegisterType( typeId, fct ); + } + + + bool Factory::isTypeSupported( const std::string& typeId ) + { + init(); + + BarcodeTypeMap::iterator i = mBarcodeTypeMap.find( typeId ); + + return ( i != mBarcodeTypeMap.end() ); + } + + + TypeIdList Factory::getSupportedTypes( void ) + { + init(); + + return mSupportedTypes; + } + + + Barcode* Factory::createBarcode( const std::string& typeId ) + { + init(); + + BarcodeTypeMap::iterator i = mBarcodeTypeMap.find( typeId ); + + if( i != mBarcodeTypeMap.end() ) + { + return i->second(); + } + + return NULL; + } + + + void Factory::internalRegisterType( const std::string& typeId, Factory::BarcodeCreateFct fct ) + { + mBarcodeTypeMap[ typeId ] = fct; + mSupportedTypes.push_back( typeId ); + } + + +} diff --git a/glbarcode/Factory.h b/glbarcode/Factory.h new file mode 100644 index 0000000..dd59db4 --- /dev/null +++ b/glbarcode/Factory.h @@ -0,0 +1,130 @@ +/* Factory.h + * + * Copyright (C) 2013-2014 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_Factory_h +#define glbarcode_Factory_h + +#include "Barcode.h" + +#include +#include +#include "TypeIdList.h" + + +/** + * Barcode factory base for CAPI + */ +extern "C" struct gbcFactory {}; + + +namespace glbarcode +{ + /** + * @class Factory Factory.h glbarcode/Factory.h + * + * Singleton Barcode factory class. + */ + class Factory : public gbcFactory + { + + public: + /** + * Barcode creation function signature. + */ + typedef Barcode* (*BarcodeCreateFct)( void ); + + + private: + /** + * Barcode factory constructor + */ + Factory(); + + + public: + /** + * Initialize barcode factory. + * + * Initializes the barcode factory and registers all built-in Barcode types. It + * is optional for an application to call init(), because glbarcode++ will automatically + * initialize the factory on demand. + */ + static void init( void ); + + + /** + * Create barcode based on type ID string. + * + * @param[in] typeId Barcode type ID string + */ + static Barcode* createBarcode( const std::string& typeId ); + + + /** + * Register barcode type ID. + * + * @param[in] typeId Barcode type ID string + * @param[in] fct Function to create barcode object of concrete Barcode class + */ + static void registerType( const std::string& typeId, BarcodeCreateFct fct ); + + + /** + * Is barcode type supported? + * + * @param[in] typeId Barcode type ID string + */ + static bool isTypeSupported( const std::string& typeId ); + + + /** + * Get list of supported types. + */ + static TypeIdList getSupportedTypes( void ); + + + private: + /** + * Internal register barcode type ID. + * + * @param[in] typeId Barcode type ID string + * @param[in] fct Function to create barcode object of concrete Barcode class + */ + static void internalRegisterType( const std::string& typeId, BarcodeCreateFct fct ); + + + /** + * Map barcode type strings to creation functions. + */ + typedef std::map BarcodeTypeMap; + static BarcodeTypeMap mBarcodeTypeMap; + + + /** + * Supported barcode types. + */ + static TypeIdList mSupportedTypes; + + }; + +} + + +#endif // glbarcode_Factory_h diff --git a/glbarcode/Matrix.h b/glbarcode/Matrix.h new file mode 100644 index 0000000..e7784c5 --- /dev/null +++ b/glbarcode/Matrix.h @@ -0,0 +1,220 @@ +/* Matrix.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_Matrix_h +#define glbarcode_Matrix_h + + +namespace glbarcode +{ + + /** + * @class Matrix Matrix.h glbarcode/Matrix.h + * + * Simple 2D Matrix implementation + */ + template class Matrix + { + + public: + /** + * Default constructor. + */ + Matrix() : mNx(0), mNy(0), mData(NULL) { } + + + /** + * Sized constructor. + */ + Matrix( int nx, int ny ) : mNx(nx), + mNy(ny), + mData((nx > 0 && ny > 0) ? new T[nx * ny] : NULL) { } + + + /** + * Copy constructor. + */ + Matrix( const Matrix& src ) : mNx(src.mNx), + mNy(src.mNy), + mData((src.mNx > 0 && src.mNy > 0) ? new T[src.mNx * src.mNy] : NULL) + { + for ( int iy = 0; iy < mNy; iy++ ) + { + for ( int ix = 0; ix < mNx; ix++ ) + { + (*this)[iy][ix] = src[iy][ix]; + } + } + } + + + /** + * Submatrix copy constructor. + */ + Matrix( const Matrix& src, + int x0, + int y0, + int nx, + int ny ) : mNx(nx), + mNy(ny), + mData((nx > 0 && ny > 0) ? new T[nx * ny] : NULL) + { + for ( int iy = 0; iy < mNy; iy++ ) + { + if ( (y0+iy) < src.ny() ) + { + for ( int ix = 0; ix < mNx; ix++ ) + { + if ( (x0+ix) < src.nx() ) + { + (*this)[iy][ix] = src[y0+iy][x0+ix]; + } + } + } + } + } + + + /** + * Destructor. + */ + ~Matrix() + { + if ( mData != NULL ) + { + delete[] mData; + } + } + + + /** + * Indirection "[]" operator + */ + inline T* operator[]( int i ) + { + return (mData + (mNx * i)); + } + + + /** + * Indirection "[]" operator + */ + inline T const*const operator[]( int i ) const + { + return (mData + (mNx * i)); + } + + + /** + * Resize (destroys old content) + */ + inline void resize( int nx, int ny ) + { + if ( mData != NULL ) + { + delete[] mData; + } + mNx = nx; + mNy = ny; + mData = (nx > 0 && ny > 0) ? new T[nx * ny] : NULL; + } + + + /** + * Get accessor for "nx" parameter. + * + * @returns Value of "nx" parameter + */ + inline int nx( void ) const + { + return mNx; + } + + + /** + * Get accessor for "ny" parameter. + * + * @returns Value of "ny" parameter + */ + inline int ny( void ) const + { + return mNy; + } + + + /** + * Extract sub-matrix from this matrix + */ + inline Matrix subMatrix( int x0, int y0, int nx, int ny ) + { + return Matrix( *this, x0, y0, nx, ny ); + } + + + /** + * Set sub-matrix + */ + inline void setSubMatrix( int x0, int y0, Matrix & a ) + { + for ( int iy = 0; iy < a.ny(); iy++ ) + { + if ( (y0 + iy) < mNy ) + { + for ( int ix = 0; ix < a.nx(); ix++ ) + { + if ( (x0 + ix) < mNx ) + { + (*this)[y0+iy][x0+ix] = a[iy][ix]; + } + } + } + } + } + + + /** + * Fill matrix with single value + */ + inline void fill( T val ) + { + for ( int iy = 0; iy < mNy; iy++ ) + { + for ( int ix = 0; ix < mNx; ix++ ) + { + (*this)[iy][ix] = val; + } + } + } + + + private: + /** + * Matrix Private data + */ + int mNx; + int mNy; + T* mData; + + }; + +} + + +#endif // glbarcode_Matrix_h diff --git a/glbarcode/QtRenderer.cpp b/glbarcode/QtRenderer.cpp new file mode 100644 index 0000000..924057b --- /dev/null +++ b/glbarcode/QtRenderer.cpp @@ -0,0 +1,187 @@ +/* QtRenderer.cpp + * + * Copyright (C) 2017 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "QtRenderer.h" + +#include +#include +#include + + +namespace glbarcode +{ + + struct QtRenderer::PrivateData + { + QPainter* painter; + QColor color; + }; + + + QtRenderer::QtRenderer() + { + d = new QtRenderer::PrivateData; + + d->painter = nullptr; + } + + + QtRenderer::QtRenderer( QPainter* painter ) + { + d = new QtRenderer::PrivateData; + + setPainter( painter ); + } + + + QtRenderer::QtRenderer( const QtRenderer& from ) + { + d = new QtRenderer::PrivateData; + + *d = *from.d; + } + + + QtRenderer::~QtRenderer() + { + delete d; + } + + + QtRenderer& QtRenderer::operator=( const QtRenderer& from ) + { + *d = *from.d; + + return *this; + } + + + QPainter* QtRenderer::painter( void ) const + { + return d->painter; + } + + + QtRenderer& QtRenderer::setPainter( QPainter* painter ) + { + d->painter = painter; + + return *this; + } + + + void QtRenderer::drawBegin( double w, double h ) + { + if ( d->painter ) + { + d->painter->save(); + d->color = d->painter->pen().color(); // Get current pen color + } + } + + + void QtRenderer::drawEnd( void ) + { + if ( d->painter ) + { + d->painter->restore(); + } + } + + + void QtRenderer::drawLine( double x, double y, double w, double h ) + { + if ( d->painter ) + { + double x = x + w/2; // Offset line origin by 1/2 line width. + + d->painter->setPen( QPen( d->color, w ) ); + d->painter->drawLine( QPointF(x, y), QPointF(x, y+h) ); + } + } + + + void QtRenderer::drawBox( double x, double y, double w, double h ) + { + if ( d->painter ) + { + d->painter->setPen( QPen( Qt::NoPen ) ); + d->painter->setBrush( QBrush( d->color ) ); + + d->painter->drawRect( QRectF(x, y, w, h) ); + } + } + + + void QtRenderer::drawText( double x, double y, double size, const std::string& text ) + { + if ( d->painter ) + { + d->painter->setPen( QPen( d->color ) ); + + QFont font = d->painter->font(); + font.setStyleHint( QFont::Monospace ); + font.setPointSizeF( size ); + d->painter->setFont( font ); + + QFontMetrics fm( font ); + QRect rect = fm.boundingRect( QString::fromStdString(text) ); + + double xCorner = x - rect.width()/2.0; + double yCorner = y - rect.height() + fm.descent(); + + d->painter->drawText( QPointF(xCorner, yCorner), QString::fromStdString(text) ); + } + } + + + void QtRenderer::drawRing( double x, double y, double r, double w ) + { + if ( d->painter ) + { + d->painter->setPen( QPen( d->color, w ) ); + d->painter->setBrush( Qt::NoBrush ); + + d->painter->drawEllipse( QPointF(x, y), r, r ); + } + } + + + void QtRenderer::drawHexagon( double x, double y, double h ) + { + if ( d->painter ) + { + d->painter->setPen( QPen( Qt::NoPen ) ); + d->painter->setBrush( QBrush( d->color ) ); + + QPolygonF hexagon; + hexagon << QPointF( x, y ) + << QPointF( x + 0.433*h, y + 0.25*h ) + << QPointF( x + 0.433*h, y + 0.75*h ) + << QPointF( x, y + h ) + << QPointF( x - 0.433*h, y + 0.75*h ) + << QPointF( x - 0.433*h, y + 0.25*h ); + + d->painter->drawPolygon( hexagon ); + } + } + + +} diff --git a/glbarcode/QtRenderer.h b/glbarcode/QtRenderer.h new file mode 100644 index 0000000..624f4d9 --- /dev/null +++ b/glbarcode/QtRenderer.h @@ -0,0 +1,105 @@ +/* QtRenderer.h + * + * Copyright (C) 2017 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_QtRenderer_h +#define glbarcode_QtRenderer_h + + +#include "Renderer.h" + +#include + + +namespace glbarcode +{ + + /** + * @class QtRenderer QtRenderer.h glbarcode/QtRenderer.h + * + * Render to QPainter context + */ + class QtRenderer : public Renderer + { + public: + /** + * Default Constructor + */ + QtRenderer(); + + /** + * Constructor with QPainter + */ + QtRenderer( QPainter* painter ); + + /** + * Copy Constructor + */ + QtRenderer( const QtRenderer& from ); + + /** + * Destructor + */ + virtual ~QtRenderer(); + + /** Assignment operator. + * + * @param[in] from The value to assign to this object. + * + * @return A reference to this object. + */ + QtRenderer& operator=( const QtRenderer& from ); + + /** Get "painter" parameter + * + * @returns painter parameter + */ + QPainter* painter() const; + + /** Set "painter" parameter + * + * @param[in] painter pointer to QPainter + * + * @returns reference to this QtRenderer object for parameter chaining + */ + QtRenderer& setPainter( QPainter* painter ); + + + private: + /* + * Virtual methods implemented by QtRenderer. + */ + void drawBegin( double w, double h ); + void drawEnd(); + void drawLine( double x, double y, double w, double h ); + void drawBox( double x, double y, double w, double h ); + void drawText( double x, double y, double size, const std::string& text ); + void drawRing( double x, double y, double r, double w ); + void drawHexagon( double x, double y, double h ); + + /** + * Private data + */ + struct PrivateData; + PrivateData *d; + }; + +} + +#endif // glbarcode_QtRenderer_h diff --git a/glbarcode/README.md b/glbarcode/README.md new file mode 100644 index 0000000..66ed886 --- /dev/null +++ b/glbarcode/README.md @@ -0,0 +1 @@ +See https://github.com/jimevins/glbarcode for standalone version. diff --git a/glbarcode/Renderer.cpp b/glbarcode/Renderer.cpp new file mode 100644 index 0000000..cd85266 --- /dev/null +++ b/glbarcode/Renderer.cpp @@ -0,0 +1,66 @@ +/* Renderer.cpp + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#include "Renderer.h" + +#include "DrawingPrimitives.h" + + +glbarcode::Renderer::~Renderer() +{ +} + + +void glbarcode::Renderer::render( double w, double h, const std::list& primitives ) +{ + drawBegin( w, h ); + + std::list::const_iterator primitive; + + for ( primitive = primitives.begin(); primitive != primitives.end(); primitive++ ) + { + if ( DrawingPrimitiveLine* line = dynamic_cast(*primitive) ) + { + drawLine( line->x(), line->y(), line->w(), line->h() ); + } + else if ( DrawingPrimitiveBox* box = dynamic_cast(*primitive) ) + { + drawBox( box->x(), box->y(), box->w(), box->h() ); + } + else if ( DrawingPrimitiveText* text = dynamic_cast(*primitive) ) + { + drawText( text->x(), text->y(), text->size(), text->text() ); + } + else if ( DrawingPrimitiveRing* ring = dynamic_cast(*primitive) ) + { + drawRing( ring->x(), ring->y(), ring->r(), ring->w() ); + } + else if ( DrawingPrimitiveHexagon* hex = dynamic_cast(*primitive) ) + { + drawHexagon( hex->x(), hex->y(), hex->h() ); + } + else + { + // NOT REACHED + } + } + + drawEnd(); +} diff --git a/glbarcode/Renderer.h b/glbarcode/Renderer.h new file mode 100644 index 0000000..c75aa97 --- /dev/null +++ b/glbarcode/Renderer.h @@ -0,0 +1,165 @@ +/* Renderer.h + * + * Copyright (C) 2013 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_Renderer_h +#define glbarcode_Renderer_h + + +#include + +#include "DrawingPrimitives.h" + + +/** + * Renderer base for CAPI + */ +extern "C" struct gbcRenderer {}; + + +namespace glbarcode +{ + + class DrawingPrimitive; /* Forward reference to private drawing primitive class. */ + + + /** + * @class Renderer Renderer.h glbarcode/Renderer.h + * + * Base class for all renderers. + */ + class Renderer : public gbcRenderer + { + public: + /** + * Destructor. + */ + virtual ~Renderer(); + + + /** + * Render list of primitives. + * + * @param[in] w Width of barcode bounding box (points) + * @param[in] h Height of barcode bounding box (points) + * @param[in] primitives List of drawing primitives + */ + void render( double w, double h, const std::list& primitives ); + + + protected: + /** + * Draw begin. + * + * Required virtual method to perform rendering setup, such as opening devices and/or + * initializing drawing contexts. + * + * @param[in] w Width of barcode bounding box (points) + * @param[in] h Height of barcode bounding box (points) + */ + virtual void drawBegin( double w, double h ) = 0; + + + /** + * Draw end. + * + * Required virtual method to perform rendering cleanup, such as closing devices + * and/or drawing contexts. + */ + virtual void drawEnd( void ) = 0; + + + /** + * Draw line primitive. + * + * Required virtual method to draw or render line drawing primitive. + * + * @image html figure-primitive-line.svg "Line primitive properties" + * + * @param[in] x X coordinate of line's origin (points) + * @param[in] y Y coordinate of line's origin (points) + * @param[in] w Line width (points) + * @param[in] h Line height (points) + */ + virtual void drawLine( double x, double y, double w, double h ) = 0; + + + /** + * Draw box primitive. + * + * Required virtual method to draw or render box drawing primitive. + * + * @image html figure-primitive-box.svg "Box primitive properties" + * + * @param[in] x X coordinate of box's origin (points) + * @param[in] y Y coordinate of box's origin (points) + * @param[in] w Width of box (points) + * @param[in] h Height of box (points) + */ + virtual void drawBox( double x, double y, double w, double h ) = 0; + + + /** + * Draw text primitive. + * + * Required virtual method to draw or render text drawing primitive. + * + * @image html figure-primitive-text.svg "Text primitive properties" + * + * @param[in] x X coordinate of text's origin (points) + * @param[in] y Y coordinate of text's origin (points) + * @param[in] size Font size of text (points) + * @param[in] text Text + */ + virtual void drawText( double x, double y, double size, const std::string& text ) = 0; + + + /** + * Draw ring primitive. + * + * Required virtual method to draw or render ring drawing primitive. + * + * @image html figure-primitive-ring.svg "Ring primitive properties" + * + * @param[in] x X coordinate of ring's origin (points) + * @param[in] y Y coordinate of ring's origin (points) + * @param[in] r Radius of ring (points) + * @param[in] w Line width of ring (points) + */ + virtual void drawRing( double x, double y, double r, double w ) = 0; + + + /** + * Draw hexagon primitive. + * + * Required virtual method to draw or render hexagon drawing primitive. + * + * @image html figure-primitive-hexagon.svg "Hexagon primitive properties" + * + * @param[in] x X coordinate of hexagon's origin (points) + * @param[in] y Y coordinate of hexagon's origin (points) + * @param[in] h Height of hexagon (points) + */ + virtual void drawHexagon( double x, double y, double h ) = 0; + + }; + +} + +#endif // glbarcode_Renderer_h diff --git a/glbarcode/TypeIdList.h b/glbarcode/TypeIdList.h new file mode 100644 index 0000000..2a1c975 --- /dev/null +++ b/glbarcode/TypeIdList.h @@ -0,0 +1,44 @@ +/* TypeIdList.h + * + * Copyright (C) 2013-2014 Jim Evins + * + * This file is part of glbarcode++. + * + * glbarcode++ is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glbarcode++ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with glbarcode++. If not, see . + */ + +#ifndef glbarcode_TypeIdList_h +#define glbarcode_TypeIdList_h + +#include "Barcode.h" + +#include +#include + + +namespace glbarcode +{ + /** + * @class TypeIdList TypeIdList.h glbarcode/TypeIdList.h + * + * List of barcode type ID strings. + */ + class TypeIdList : public std::list + { + }; + +} + + +#endif // glbarcode_TypeIdList_h