Files
sethLabels/glbarcode/BarcodePostnet.cpp
T

186 lines
3.9 KiB
C++

/* BarcodePostnet.cpp
*
* Copyright (C) 2013 Jaye Evins <evins@snaught.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "BarcodePostnet.h"
#include "Constants.h"
#include <cctype>
#include <algorithm>
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( )
{
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 (char c : rawData)
{
if ( isdigit( c ) )
{
nDigits++;
}
else if ( (c != '-') && (c != ' ') )
{
/* 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 appropriate symbol */
int sum = 0;
for (char c : cookedData)
{
if ( isdigit( c ) )
{
/* Only translate the digits (0-9) */
int d = c - '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 (char c : codedData)
{
double y = POSTNET_VERT_MARGIN;
double length = 0;
switch ( c )
{
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;
}
double 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;
}
}