UPCE码
UPCE码绘制如下:
//UPCE
SStringW sstrContent = L"0123456";
if (sstrContent.GetLength() != 7 && sstrContent.GetLength() != 8)
{
//数据长度错误
}
//计算文本所占的大小
SIZE szContent;
pRT->MeasureText(sstrContent, sstrContent.GetLength(), &szContent);
//将绘制条码的区域跟绘制文本的区域分开(此处只考虑文本在下方的情况,如有其他的需求可自己实现)
CRect rcBar(rcWindow);
rcBar.bottom = rcBar.bottom - szContent.cy;
CRect rcText(rcWindow);
rcText.top = rcBar.bottom;
//如果是7位则需要自己计算校验码,如果是8位则需要验证一下校验码是否正确
//计算校验位
//1 3 5 7位之和得出C1
//2 4 6位之和乘以3得出C2
//C1 + C2取个位得出CC
//校验码为10 - CC如果结果为10则校验码为0
SStringW sstr1 = sstrContent.GetAt(0);
SStringW sstr2 = sstrContent.GetAt(1);
SStringW sstr3 = sstrContent.GetAt(2);
SStringW sstr4 = sstrContent.GetAt(3);
SStringW sstr5 = sstrContent.GetAt(4);
SStringW sstr6 = sstrContent.GetAt(5);
SStringW sstr7 = sstrContent.GetAt(6);
int nC1 = (std::stoi(sstr1.c_str()) + std::stoi(sstr3.c_str()) + std::stoi(sstr5.c_str()) + std::stoi(sstr7.c_str()));
int nC2 = (std::stoi(sstr2.c_str()) + std::stoi(sstr4.c_str()) + std::stoi(sstr6.c_str())) * 3;
int nCC = (nC1 + nC2) % 10;
int nCheck = 10 - nCC;
if (nCheck == 10) nCheck = 0;
if (sstrContent.GetLength() == 8)
{
SStringW sstr8 = sstrContent.GetAt(7);
int nContentCheck = std::stoi(sstr8.c_str());
if (nContentCheck != nCheck)
{
//校验码错误
}
}
SStringW sstrData = sstr1 + sstr2 + sstr3 + sstr4 + sstr5 + sstr6 + sstr7;
std::string strContent = S_CW2A(sstrData);
SStringW sstrCheck;
sstrCheck.Format(L"%d", nCheck);
struct zint_symbol* symbol;
symbol = ZBarcode_Create();
symbol->symbology = BARCODE_UPCE;
symbol->input_mode = DATA_MODE; //编码格式
int nRet = ZBarcode_Encode_and_Buffer_Vector(symbol, (unsigned char*)strContent.c_str(), strContent.size(), 0);
if (nRet == 0)
{
ZBarcode_Print(symbol, 0);
int nMinLen = 1000;
int nMaxLen = 0;
std::vector<CRect> vecLines;
if (symbol->vector)
{
struct zint_vector_rect* rect = symbol->vector->rectangles;
while (rect)
{
CRect rcTmp;
rcTmp.left = rect->x;
rcTmp.top = rect->y;
rcTmp.right = rcTmp.left + rect->width;
rcTmp.bottom = rcTmp.top + rect->height;
vecLines.push_back(rcTmp);
if (rect->height > nMaxLen) nMaxLen = rect->height;
if (rect->height < nMinLen) nMinLen = rect->height;
rect = rect->next;
}
}
double nDrawUint = (double)rcWindow.Width() / symbol->width;
double nUint = (double)symbol->bitmap_width / symbol->width;
std::vector<CRect> vecDrawLines; //绘制条码条的真实区域
double dMinReal = 0.0;
for (int i = 0; i < vecLines.size(); i++)
{
CRect rcTmp(vecLines[i]);
rcTmp.left = rcTmp.left / nUint * nDrawUint;
rcTmp.right = rcTmp.right / nUint * nDrawUint;
if (rcTmp.Height() == nMaxLen)
{
rcTmp.bottom = rcTmp.top + rcWindow.Height();
dMinReal = rcTmp.Height();
}
else
{
rcTmp.bottom = rcTmp.top + rcBar.Height();
dMinReal = rcTmp.Height();
}
vecDrawLines.push_back(rcTmp);
}
//绘制条码
std::vector<CRect> vecMinBar;
for (int i = 0; i < vecDrawLines.size(); i++)
{
COLORREF clrFrgnd = GETCOLOR(L"RGB(0,0,0)");
CAutoRefPtr<IBrush> brush, oldbrush;
pRT->CreateSolidColorBrush(clrFrgnd, &brush);
CRect rcBlack;
rcBlack.left += vecDrawLines[i].left + rcBar.left;
rcBlack.top += vecDrawLines[i].top + rcBar.top;
rcBlack.right = rcBlack.left + vecDrawLines[i].Width();
rcBlack.bottom = rcBlack.top + vecDrawLines[i].Height();
if (vecDrawLines[i].Height() == dMinReal)
vecMinBar.push_back(rcBlack);
pRT->SelectObject(brush, (IRenderObj**)&oldbrush);
pRT->FillRectangle(&rcBlack);
pRT->SelectObject(oldbrush, NULL);
}
//绘制文本
//计算各个文本绘制的区域
CRect rcStart(rcText), rcContent(rcText), rcCheck(rcText);
rcStart.right = rcStart.left + vecDrawLines[0].left - 5;
rcCheck.left = rcText.left + vecDrawLines[vecDrawLines.size() - 1].right + 5;
rcContent.left = vecMinBar[0].left;
rcContent.right = vecMinBar[vecMinBar.size() - 1].right;
//绘制第一位
pRT->DrawText(sstr1, -1, (LPRECT)rcStart, DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
//绘制校验位
pRT->DrawText(sstrCheck, -1, (LPRECT)rcCheck, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
{
//绘制中间部分
SStringW sstrDrawContent = sstr2 + sstr3 + sstr4 + sstr5 + sstr6 + sstr7;
pRT->DrawText(sstrDrawContent, -1, (LPRECT)rcContent, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
}
}