Code:
// BC128.C
#include <stdio.h>
#include <stdlib.h>
struct BarCode128 {
int iFlags;
char *pText;
char *pPartialData;
char *pTextInformation;
int iWidth, iHeight;
int iXoffset, iYoffset;
int iMargin;
double fBarCodeScale;
};
static char *cBarcode128Set[] = {
"212222", "222122", "222221", "121223", "121322",
"131222", "122213", "122312", "132212", "221213",
"221312", "231212", "112232", "122132", "122231",
"113222", "123122", "123221", "223211", "221132",
"221231", "213212", "223112", "312131", "311222",
"321122", "321221", "312212", "322112", "322211",
"212123", "212321", "232121", "111323", "131123",
"131321", "112313", "132113", "132311", "211313",
"231113", "231311", "112133", "112331", "132131",
"113123", "113321", "133121", "313121", "211331",
"231131", "213113", "213311", "213131", "311123",
"311321", "331121", "312113", "312311", "332111",
"314111", "221411", "431111", "111224", "111422",
"121124", "121421", "141122", "141221", "112214",
"112412", "122114", "122411", "142112", "142211",
"241211", "221114", "413111", "241112", "134111",
"111242", "121142", "121241", "114212", "124112",
"124211", "411212", "421112", "421211", "212141",
"214121", "412121", "111143", "111341", "131141",
"114113", "114311", "411113", "411311", "113141",
"114131", "311141", "411131", "b1a4a2", "b1a2a4",
"b1a2c2", "b3c1a1b"
};
#define START_A 103
#define START_B 104
#define START_C 105
#define STOP 106
#define SHIFT 98
#define CODE_A 101
#define CODE_B 100
#define CODE_C 99
#define FUNC_1 102
#define FUNC_2 97
#define FUNC_3 96
#define BAR_WIDTH 11
#define BAR_REDUCTION 0.15
#define BARCODE_DEFAULT_MARGIN 10
#define BARCODE_NO_ASCII 0x00000100
#define BARCODE_OUT_PCL 0x00000200
#define BARCODE_OUT_PCL_III 0x00000300
enum {
BARCODE_128C = 0,
BARCODE_128B
};
int Verify128B(unsigned char *pText)
{
if (pText[0] == '\0')
return -1;
while (*pText && *pText>=32 && !(*pText & 0x80))
pText++;
if (*pText)
return -1;
return 0;
}
int Encode128B(struct BarCode128 *pBarCode)
{
static char *pText;
static char *pPartialData;
static char *pTextInfo;
char *pTextPtr;
int iIndex, iCode, iTextPosition, iCheckSum = 0;
if (pBarCode->pPartialData)
free(pBarCode->pPartialData);
if (pBarCode->pTextInformation)
free(pBarCode->pTextInformation);
pBarCode->pPartialData = pBarCode->pTextInformation = NULL;
pText = pBarCode->pText;
if (!pText)
return -1;
pPartialData = malloc( (strlen(pText) + 4) * 6 + 2);
if (!pPartialData)
return -1;
pTextInfo = malloc(10*strlen(pText) + 2);
if (!pTextInfo)
{
free(pPartialData);
return -1;
}
strcpy(pPartialData, "0");
strcat(pPartialData, cBarcode128Set[START_B]);
iCheckSum += START_B;
pTextPtr = pTextInfo;
iTextPosition = BAR_WIDTH;
for (iIndex = 0; iIndex < strlen(pText); iIndex++)
{
if ( pText[iIndex] < 32 || (pText[iIndex] & 0x80))
{
free(pPartialData);
free(pTextInfo);
return -1;
}
iCode = pText[iIndex]-32;
strcat(pPartialData, cBarcode128Set[iCode]);
iCheckSum += iCode * (iIndex + 1);
sprintf(pTextPtr, "%i:12:%c ", iTextPosition, pText[iIndex]);
pTextPtr += strlen(pTextPtr);
iTextPosition += BAR_WIDTH;
}
pTextPtr[-1] = '\0';
iCheckSum %= 103;
strcat(pPartialData, cBarcode128Set[iCheckSum]);
strcat(pPartialData, cBarcode128Set[STOP]);
pBarCode->pPartialData = pPartialData;
pBarCode->pTextInformation = pTextInfo;
return 0;
}
int Verify128C(unsigned char *pText)
{
if (pText[0] == '\0')
return -1;
if (strlen(pText) % 2)
return -1;
for (; *pText; pText++)
if (!isdigit(*pText))
return -1;
return 0;
}
int Encode128C(struct BarCode128 *pBarCode)
{
static char *pText;
static char *pPartial;
static char *pTextInfo;
char *pTextPtr;
int iIndex, iCode, iTextPos, iCheckSum = 0;
if (pBarCode->pPartialData)
free(pBarCode->pPartialData);
if (pBarCode->pTextInformation)
free(pBarCode->pTextInformation);
pBarCode->pPartialData = pBarCode->pTextInformation = NULL;
pText = pBarCode->pText;
if (!pText)
return -1;
pPartial = malloc( (strlen(pText) + 3) * 6 + 2);
if (!pPartial)
return -1;
pTextInfo = malloc(12*strlen(pText) + 2);
if (!pTextInfo)
{
free(pPartial);
return -1;
}
strcpy(pPartial, "0");
strcat(pPartial, cBarcode128Set[START_C]);
iCheckSum += START_C;
pTextPtr = pTextInfo;
iTextPos = BAR_WIDTH;
for (iIndex = 0; pText[iIndex]; iIndex += 2)
{
if (!isdigit(pText[iIndex]) || !isdigit(pText[iIndex+1]))
{
free(pPartial);
free(pTextInfo);
return -1;
}
iCode = (pText[iIndex]-'0') * 10 + pText[iIndex+1] - '0';
strcat(pPartial, cBarcode128Set[iCode]);
iCheckSum += iCode * (iIndex / 2 + 1);
sprintf(pTextPtr, "%g:9:%c %g:9:%c ", (double)iTextPos, pText[iIndex],
iTextPos + (double)BAR_WIDTH / 2, pText[iIndex+1]);
pTextPtr += strlen(pTextPtr);
iTextPos += BAR_WIDTH;
}
pTextPtr[-1] = '\0';
iCheckSum %= 103;
strcat(pPartial, cBarcode128Set[iCheckSum]);
strcat(pPartial, cBarcode128Set[STOP]);
pBarCode->pPartialData = pPartial;
pBarCode->pTextInformation = pTextInfo;
return 0;
}
int PclPrint(struct BarCode128 *pBarCode, FILE *f)
{
int iIndex, j, k, iBarLength;
double fTemp1, fTemp2, fSave = 0;
int iMode = '-';
double fScale=1, iXposition, iX0, iY0, iYr;
unsigned char *pPtr;
unsigned char c;
char cFontID[6];
if (!pBarCode->pPartialData || !pBarCode->pTextInformation)
return -1;
iBarLength = pBarCode->pPartialData[0] - '0';
for (pPtr = pBarCode->pPartialData+1; *pPtr; pPtr++)
if (isdigit(*pPtr))
iBarLength += (*pPtr - '0');
else if (islower(*pPtr))
iBarLength += (*pPtr - 'a' + 1);
if (!pBarCode->fBarCodeScale)
{
if (!pBarCode->iWidth) pBarCode->iWidth = iBarLength;
fScale = pBarCode->fBarCodeScale = (double)pBarCode->iWidth / (double)iBarLength;
}
if (!pBarCode->iWidth) pBarCode->iWidth = iBarLength * fScale +1;
if (pBarCode->iWidth < iBarLength * fScale) {
int wid = iBarLength * fScale + 1;
pBarCode->iXoffset -= (wid - pBarCode->iWidth) / 2;
pBarCode->iWidth = wid;
if (pBarCode->iXoffset < 0)
{
pBarCode->iWidth += -pBarCode->iXoffset;
pBarCode->iXoffset = 0;
}
}
if (!pBarCode->iHeight) pBarCode->iHeight = 80 * fScale;
iIndex = 5 + 10 * ((pBarCode->iFlags & BARCODE_NO_ASCII) == 0);
if (pBarCode->iHeight < iIndex * fScale )
{
double scaleg = ((double)pBarCode->iHeight) / iIndex;
int wid = pBarCode->iWidth * scaleg / fScale;
pBarCode->iXoffset += (pBarCode->iWidth - wid) / 2;
pBarCode->iWidth = wid;
fScale = scaleg;
}
iXposition = pBarCode->iMargin + (pBarCode->pPartialData[0] - '0') * fScale;
for (pPtr = pBarCode->pPartialData+1, iIndex = 1; *pPtr; pPtr++, iIndex++)
{
if (*pPtr == '+' || *pPtr == '-')
iMode = *pPtr; iIndex++; continue;
if (isdigit (*pPtr)) j = *pPtr - '0';
else j = *pPtr - 'a' + 1;
if (iIndex % 2)
{
iX0 = pBarCode->iXoffset + iXposition;
iY0 = pBarCode->iYoffset + pBarCode->iMargin;
iYr = pBarCode->iHeight;
if (!(pBarCode->iFlags & BARCODE_NO_ASCII))
{
if (iMode == '-')
iYr -= (isdigit(*pPtr) ? 10 : 5) * fScale;
else
{
iY0 += (isdigit(*pPtr) ? 10 : 0) * fScale;
iYr -= (isdigit(*pPtr) ? 20 : 10) * fScale;
}
}
fprintf(f,"%c&a%.0fH", 27, iX0 * 10.0);
fprintf(f,"%c&a%.0fV", 27, iY0 * 10.0);
fprintf(f,"%c*c%.0fH", 27, ((j*fScale)-BAR_REDUCTION) * 10.0);
fprintf(f,"%c*c%.0fV", 27, iYr * 10.0);
fprintf(f,"%c*c0P\n", 27);
}
iXposition += j * fScale;
}
iMode = '-';
if (!(pBarCode->iFlags & BARCODE_NO_ASCII))
{
k=0;
for (pPtr = pBarCode->pTextInformation; pPtr; pPtr = strchr(pPtr, ' '))
{
while (*pPtr == ' ') pPtr++;
if (!*pPtr) break;
if (*pPtr == '+' || *pPtr == '-')
iMode = *pPtr; continue;
if (sscanf(pPtr, "%lf:%lf:%c", &fTemp1, &fTemp2, &c) != 3)
{
fprintf(stderr, "Cannot print: %s\n", pPtr);
continue;
}
if (fSave != fTemp2)
{
if ((pBarCode->iFlags & BARCODE_OUT_PCL_III) == BARCODE_OUT_PCL_III)
strcpy(cFontID, "4148");
else
strcpy(cFontID, "16602");
fprintf(f,"%c(8U%c(s1p%5.2fv0s0b%sT", 27, 27, fTemp2 * fScale, cFontID);
}
fSave = fTemp2;
fprintf(f,"%c&a%.0fH", 27, (pBarCode->iXoffset + fTemp1 * fScale + pBarCode->iMargin) * 10.0);
fprintf(f,"%c&a%.0fV", 27,
iMode != '-'
? ((double)pBarCode->iYoffset + pBarCode->iMargin + 8*fScale) * 10.0
: ((double)pBarCode->iYoffset + pBarCode->iMargin + pBarCode->iHeight) * 10.0);
fprintf(f, "%c", c);
}
}
return 0;
}
int DeleteBarcode(struct BarCode128 *pBarCode)
{
if (pBarCode->pText)
free(pBarCode->pText);
if (pBarCode->pPartialData)
free(pBarCode->pPartialData);
if (pBarCode->pTextInformation)
free(pBarCode->pTextInformation);
free(pBarCode);
return 0;
}
int EncodeBarcode(struct BarCode128 *pBarCode, int iFlags)
{
int ret = 0;
if(iFlags == BARCODE_128B)
{
if (Verify128B(pBarCode->pText) != 0)
return -1;
}
if(iFlags == BARCODE_128C)
{
if (Verify128C(pBarCode->pText) != 0)
return -1;
}
if(iFlags == BARCODE_128B)
ret = Encode128B(pBarCode);
if(iFlags == BARCODE_128C)
ret = Encode128C(pBarCode);
return ret;
}
struct BarCode128 *Barcode_Create(char *pText)
{
struct BarCode128 *pBarCode;
pBarCode = malloc(sizeof(*pBarCode));
if (!pBarCode) return NULL;
memset(pBarCode, 0, sizeof(*pBarCode));
pBarCode->pText = strdup(pText);
pBarCode->iMargin = BARCODE_DEFAULT_MARGIN;
return pBarCode;
}
int PositionBarcode(struct BarCode128 *pBarCode, int iWidth, int iHeight,
int iXoffset, int iYoffset, double fScale)
{
pBarCode->iWidth = iWidth; pBarCode->iHeight = iHeight;
pBarCode->iXoffset = iXoffset; pBarCode->iYoffset = iYoffset;
pBarCode->fBarCodeScale = fScale;
return 0;
}
int main(void)
{
FILE *outfile;
struct BarCode128 * pBarCode;
if((outfile=fopen("LPT1","w")) == NULL)
return -1;
if (!(pBarCode=Barcode_Create("254896587")))
{
fclose(outfile);
return -1;
}
PositionBarcode(pBarCode, 0, 0, 40, 530, 0.0);
EncodeBarcode(pBarCode,BARCODE_128C );
PclPrint(pBarCode, outfile);
DeleteBarcode(pBarCode);
if (!(pBarCode=Barcode_Create("35DarkDucke23was56here")))
{
fclose(outfile);
return -1;
}
PositionBarcode(pBarCode, 0, 60, 240, 510, 0.0);
EncodeBarcode(pBarCode,BARCODE_128B );
PclPrint(pBarCode, outfile);
DeleteBarcode(pBarCode);
fclose(outfile);
return 0;
}