static QPointF addElement(OROPage * page, const QRectF &r, QPointF startPos, ORBarcodeData * bc, qreal width, bool isSpace) { QPen pen(Qt::NoPen); QBrush brush(QColor("black")); if(!isSpace) { ORORect * rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(startPos.x(),startPos.y(), width, r.height())); rect->setRotationAxis(bc->rect.topLeft()); page->addPrimitive(rect); } return QPointF(startPos.x() + width, startPos.y()); }
void printRR(OROPage *page,ORBarcodeData *bc,const QRectF &qrect) { ORORect * rect = NULL; QPen pen(Qt::NoPen); QBrush brush(QColor("black")); qreal Xo = qrect.left(); qreal Yo = qrect.bottom(); //length of square qreal pas = std::min(qrect.width()/7, qrect.height()/4); //draw the RR rect = new ORORect(bc); rect->setPen(pen); brush.setColor(Qt::black); rect->setBrush(brush); for(int t = 0; t <= 1; t++) { for(int y=0; y<4; y++) { rect = new ORORect(bc); rect->setBrush(brush); rect->setRect(QRectF( Xo + t*4*pas, Yo - y*pas, pas, pas)); rect->setRotationAxis(qrect.topLeft()); page->addPrimitive(rect); //delete rect; rect = new ORORect(bc); rect->setBrush(brush); rect->setRect(QRectF( Xo + ((y + 1)%2 + 1 + t*4)*pas, Yo - y*pas, pas, pas)); rect->setRotationAxis(qrect.topLeft()); page->addPrimitive(rect); //delete rect; } } }
void render3of9(OROPage * page, const QRectF & r, const QString & _str, ORBarcodeData * bc) { QString str = _str; // lets determine some core attributes about this barcode qreal narrow_bar = bc->narrowBarWidth; qreal interchange_gap = narrow_bar; // the space between each 'set' of bars int bar_width_mult = 2; // the wide bar width multiple of the narrow bar // this is our mandatory minimum quiet zone qreal quiet_zone = narrow_bar * 10; if(quiet_zone < 0.1) quiet_zone = 0.1; // what kind of area do we have to work with qreal draw_width = r.width(); qreal draw_height = r.height(); // how long is the value we need to encode? int val_length = str.length(); // L = (C + 2)(3N + 6)X + (C + 1)I // L length of barcode (excluding quite zone) in units same as X and I // C the number of characters in the value excluding the start/stop // N the bar width multiple for wide bars // X the width of a bar (pixels in our case) // I the interchange gap in the same units as X (value is same as X for our case) qreal L; qreal C = val_length; qreal N = bar_width_mult; qreal X = narrow_bar; qreal I = interchange_gap; L = ((C + 2.0) * (3.0*N + 6.0) * X) + ((C + 1.0) * I); // now we have the actual width the barcode will be so can determine the actual // size of the quiet zone (we assume we center the barcode in the given area // what should we do if the area is too small???? // At the moment the way the code is written is we will always start at the minimum // required quiet zone if we don't have enough space.... I guess we'll just have over-run // to the right // // calculate the starting position based on the alignment option // for left align we don't need to do anything as the values are already setup for it if(bc->align == 1) // center { qreal nqz = (draw_width - L) / 2.0; if(nqz > quiet_zone) quiet_zone = nqz; } else if(bc->align > 1) // right quiet_zone = draw_width - (L + quiet_zone); //else if(align < 1) {} // left : do nothing qreal pos = r.left() + quiet_zone; qreal top = r.top(); // ok we need to prepend and append the str with a * str = QString().sprintf("*%s*",str.toLatin1().data()); QPen pen(Qt::NoPen); QBrush brush(QColor("black")); for(int i = 0; i < str.length(); i++) { // loop through each char and render the barcode QChar c = str.at(i); int idx = codeIndex(c); if(idx == -1) { qDebug("Encountered a non-compliant character while rendering a 3of9 barcode -- skipping"); continue; } bool space = false; for(int b = 0; b < 9; b++, space = !space) { qreal w = (_3of9codes[idx].values[b] == 1 ?narrow_bar*bar_width_mult:narrow_bar); if(!space) { ORORect * rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, w,draw_height)); page->addPrimitive(rect); } pos += w; } pos += interchange_gap; } return; }
void renderCodeEAN13(OROPage * page, const QRectF & r, const QString & _str, ORBarcodeData * bc) { int val[13]; int i = 0; // initialize all the values just so we can be predictable for(i = 0; i < 13; i++) val[i] = -1; // verify that the passed in string is valid // if it's not either twelve or thirteen characters // then it must be invalid to begin with if(_str.length() != 12 && _str.length() != 13) return; // loop through and convert each char to a digit. // if we can't convert all characters then this is // an invalid number for(i = 0; i < _str.length(); i++) { val[i] = ((QChar)_str.at(i)).digitValue(); if(val[i] == -1) return; } // calculate and append the checksum value int old_sum = val[12]; // get the old check sum value (-1 if none was set) int checksum = 0; for(i = 0; i < 12; i++) checksum += val[i] * (i % 2 ? 3 : 1); checksum = (checksum % 10); if(checksum) checksum = 10 - checksum; val[12] = checksum; // if we had an old checksum value and if it doesn't match what we came // up with then the string must be invalid so we will bail if(old_sum != -1 && old_sum != checksum) return; // lets determine some core attributes about this barcode qreal bar_width = bc->narrowBarWidth; // this is are mandatory minimum quiet zone qreal quiet_zone = bar_width * 10; if(quiet_zone < 0.1) quiet_zone = 0.1; // what kind of area do we have to work with qreal draw_width = r.width(); qreal draw_height = r.height() - 0.02; // L = 95X // L length of barcode (excluding quite zone) in units same as X and I // X the width of a bar (pixels in our case) qreal L; qreal X = bar_width; L = (95.0 * X); // now we have the actual width the barcode will be so can determine the actual // size of the quiet zone (we assume we center the barcode in the given area // what should we do if the area is too small???? // At the moment the way the code is written is we will always start at the minimum // required quiet zone if we don't have enough space.... I guess we'll just have over-run // to the right // // calculate the starting position based on the alignment option // for left align we don't need to do anything as the values are already setup for it if(bc->align == 1) // center { qreal nqz = (draw_width - L) / 2; if(nqz > quiet_zone) quiet_zone = nqz; } else if(bc->align > 1) // right quiet_zone = draw_width - (L + quiet_zone); // else if(align < 1) {} // left : do nothing qreal pos = r.left() + quiet_zone; qreal top = r.top(); QPen pen(Qt::NoPen); QBrush brush(QColor("black")); int b = 0; int w = 0; // render open guard ORORect * rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += (bar_width * 2.0); rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += bar_width; // render first set for(i = 0; i < 6; i++) { b = val[i+1]; for(w = 0; w < 7; w++) { if(_encodings[b][_parity[val[0]][i]][w]) { rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height-0.07)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); } pos += bar_width; } } // render center guard pos += bar_width; rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += (bar_width * 2.0); rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += (bar_width * 2.0); // render last set for(i = 0; i < 6; i++) { b = val[i+7]; for(w = 0; w < 7; w++) { if(_encodings[b][RIGHTHAND][w]) { rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height-0.07)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); } pos += bar_width; } } // render close guard rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += (bar_width * 2.0); rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); QString parstr = QString("%1").arg(val[0]); QString leftstr = QString().sprintf("%d%d%d%d%d%d", val[1], val[2], val[3], val[4], val[5], val[6]); QString rightstr = QString().sprintf("%d%d%d%d%d%d", val[7], val[8], val[9], val[10], val[11], val[12]); QFont font("Arial", 6); OROTextBox * tb = new OROTextBox(bc); tb->setPosition(QPointF(r.left(), r.top() + draw_height - 0.12)); tb->setSize(QSizeF(quiet_zone - 0.02, 0.12)); tb->setFont(font); tb->setText(parstr); tb->setFlags(Qt::AlignRight | Qt::AlignTop); rect->setRotationAxis(r.topLeft()); page->addPrimitive(tb); tb = new OROTextBox(bc); tb->setPosition(QPointF(r.left() + quiet_zone + 0.03, (r.top() + draw_height) - 0.07)); tb->setSize(QSizeF(0.42, 0.1)); tb->setFont(font); tb->setText(leftstr); tb->setFlags(Qt::AlignHCenter | Qt::AlignTop); rect->setRotationAxis(r.topLeft()); page->addPrimitive(tb); tb = new OROTextBox(bc); tb->setPosition(QPointF(r.left() + quiet_zone + 0.5, (r.top() + draw_height) - 0.07)); tb->setSize(QSizeF(0.42, 0.1)); tb->setFont(font); tb->setText(rightstr); tb->setFlags(Qt::AlignHCenter | Qt::AlignTop); rect->setRotationAxis(r.topLeft()); page->addPrimitive(tb); return; }
void renderCode128(OROPage * page, const QRectF & r, const QString & _str, ORBarcodeData * bc) { QVector<int> str; int i = 0; // create the list.. if the list is empty then just set a start code and move on if(_str.isEmpty()) str.push_back(104); else { int rank_a = 0; int rank_b = 0; int rank_c = 0; QChar c; for(i = 0; i < _str.length(); i++) { c = _str.at(i); rank_a += (code128Index(c, SETA) != -1 ? 1 : 0); rank_b += (code128Index(c, SETB) != -1 ? 1 : 0); rank_c += (c >= '0' && c <= '9' ? 1 : 0); } if(rank_c == _str.length() && ((rank_c % 2) == 0 || rank_c > 4)) { // every value in the is a digit so we are going to go with mode C // and we have an even number or we have more than 4 values i = 0; if((rank_c % 2) == 1) { str.push_back(104); // START B c = _str.at(0); str.push_back(code128Index(c, SETB)); str.push_back(99); // MODE C i = 1; } else str.push_back(105); // START C for(i = i; i < _str.length(); i+=2) { char a, b; c = _str.at(i); a = c.toAscii(); a -= 48; c = _str.at(i+1); b = c.toAscii(); b -= 48; str.push_back(int((a * 10) + b)); } } else { // start in the mode that had the higher number of hits and then // just shift into the opposite mode as needed int set = ( rank_a > rank_b ? SETA : SETB ); str.push_back(( rank_a > rank_b ? 103 : 104 )); int v = -1; for(i = 0; i < _str.length(); i++) { c = _str.at(i); v = code128Index(c, set); if(v == -1) { v = code128Index(c, (set == SETA ? SETB : SETA)); if(v != -1) { str.push_back(98); // SHIFT str.push_back(v); } } else str.push_back(v); } } } // calculate and append the checksum value to the list int checksum = str.at(0); for(i = 1; i < str.size(); i++) checksum += (str.at(i) * i); checksum = checksum % 103; str.push_back(checksum); // lets determine some core attributes about this barcode qreal bar_width = bc->narrowBarWidth; // this is are mandatory minimum quiet zone qreal quiet_zone = bar_width * 10; if(quiet_zone < 0.1) quiet_zone = 0.1; // what kind of area do we have to work with qreal draw_width = r.width(); qreal draw_height = r.height(); // how long is the value we need to encode? int val_length = str.size() - 2; // we include start and checksum in are list so // subtract them out for our calculations // L = (11C + 35)X // L length of barcode (excluding quite zone) in units same as X and I // C the number of characters in the value excluding the start/stop and checksum characters // X the width of a bar (pixels in our case) qreal L; qreal C = val_length; qreal X = bar_width; L = (((11.0 * C) + 35.0) * X); // now we have the actual width the barcode will be so can determine the actual // size of the quiet zone (we assume we center the barcode in the given area // what should we do if the area is too small???? // At the moment the way the code is written is we will always start at the minimum // required quiet zone if we don't have enough space.... I guess we'll just have over-run // to the right // // calculate the starting position based on the alignment option // for left align we don't need to do anything as the values are already setup for it if(bc->align == 1) // center { qreal nqz = (draw_width - L) / 2.0; if(nqz > quiet_zone) quiet_zone = nqz; } else if(bc->align > 1) // right quiet_zone = draw_width - (L + quiet_zone); // else if(align < 1) {} // left : do nothing qreal pos = r.left() + quiet_zone; qreal top = r.top(); QPen pen(Qt::NoPen); QBrush brush(QColor("black")); bool space = false; int idx = 0, b = 0; qreal w = 0.0; for(i = 0; i < str.size(); i++) { // loop through each value and render the barcode idx = str.at(i); if(idx < 0 || idx > 105) { qDebug("Encountered a non-compliant element while rendering a 3of9 barcode -- skipping"); continue; } space = false; for(b = 0; b < 6; b++, space = !space) { w = _128codes[idx].values[b] * bar_width; if(!space) { ORORect * rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, w,draw_height)); page->addPrimitive(rect); } pos += w; } } // we have to do the stop character seperatly like this because it has // 7 elements in it's bar sequence rather than 6 like the others int STOP_CHARACTER[]={ 2, 3, 3, 1, 1, 1, 2 }; space = false; for(b = 0; b < 7; b++, space = !space) { w = STOP_CHARACTER[b] * bar_width; if(!space) { ORORect * rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, w,draw_height)); page->addPrimitive(rect); } pos += w; } return; }
void renderCodeDatamatrix(OROPage *page, const QRectF &qrect, const QString &qstr, ORBarcodeData * bc) { //5 pixel par carré //qreal pix = 5; //lecture du type de datamatrix QRegExp regex("[a-zA-Z]{10}_([0-9]{1,2})_([LCR]{1})"); regex.indexIn(bc->format); int type = regex.cap(1).toInt(); QString align = regex.cap(2); size_t width, height, bytesPerPixel; //pointer declaration unsigned char *pxl = NULL; DmtxEncode *enc = NULL; DmtxImage *img = NULL; ORORect *rect = NULL; int valeur = 0; /* 1) ENCODE a new Data Matrix barcode image (in memory only) */ enc = dmtxEncodeCreate(); //see DmtxSymbolSize in dmtx.h for more details enc->sizeIdxRequest = type; enc->marginSize = 0; //number of pixel for one square enc->moduleSize = 1; try { //assert(enc != NULL); dmtxEncodeDataMatrix(enc, qstr.size(), (unsigned char*)qstr.toStdString().c_str()); /* 2) COPY the new image data before releasing encoding memory */ width = dmtxImageGetProp(enc->image, DmtxPropWidth); height = dmtxImageGetProp(enc->image, DmtxPropHeight); bytesPerPixel = dmtxImageGetProp(enc->image, DmtxPropBytesPerPixel); if(width > 1000000000) { throw std::runtime_error("Code is to big for the Datamatrix"); } pxl = (unsigned char *)malloc(width * height * bytesPerPixel); //assert(pxl != NULL); memcpy(pxl, enc->image->pxl, width * height * bytesPerPixel); dmtxEncodeDestroy(&enc); /* 3) DECODE the Data Matrix barcode from the copied image */ img = dmtxImageCreate(pxl, width, height, DmtxPack24bppRGB); QPen pen(Qt::NoPen); QBrush brush(QColor("black")); qreal Xo = 0; qreal Yo = 0; //length of square qreal pas = 0; datamatrixGeometry(align,qrect,img,&Xo,&Yo,&pas); //draw the datamatrix for(int y = 0; y < img->height; y++) { for(int x = 0; x < img->width; x++) { dmtxImageGetPixelValue(img,x,y,0,&valeur); rect = new ORORect(bc); rect->setPen(pen); if(valeur == 0) { brush.setColor(Qt::black); rect->setBrush(brush); rect->setRect(QRectF( Xo + x*pas, Yo - y*pas, pas, pas)); rect->setRotationAxis(qrect.topLeft()); page->addPrimitive(rect); } } delete rect; } //memory cleanning free(pxl); dmtxEncodeDestroy(&enc); dmtxImageDestroy(&img); } catch(...) { //there is a problem with the datamatrix //RR is printed printRR(page,bc,qrect); //memory cleaning if(rect != NULL) { delete rect; } if(enc != NULL) { dmtxEncodeDestroy(&enc); } if(img != NULL) { dmtxImageDestroy(&img); } if(pxl!=NULL) { free(pxl); } } }
void renderCodeUPCE(OROPage * page, const QRectF & r, const QString & _str, int align) { int val[8]; int i = 0; // initialize all the values just so we can be predictable for(i = 0; i < 8; i++) val[i] = -1; // verify that the passed in string is valid // if it's not either twelve or thirteen characters // then it must be invalid to begin with if(_str.length() != 8) return; // loop through and convert each char to a digit. // if we can't convert all characters then this is // an invalid number for(i = 0; i < _str.length(); i++) { val[i] = ((QChar)_str.at(i)).digitValue(); if(val[i] == -1) return; } // calculate and append the checksum value // because everything is so messed up we don't calculate // the checksum and require that it be passed in already // however we do have to verify that the first digit is // either 0 or 1 as that is our parity if(val[0] != 0 && val[0] != 1) return; // lets determine some core attributes about this barcode qreal bar_width = 0.01; // the width of the base unit bar // this is are mandatory minimum quiet zone qreal quiet_zone = bar_width * 0.10; if(quiet_zone < 0.10) quiet_zone = 0.10; // what kind of area do we have to work with qreal draw_width = r.width(); qreal draw_height = r.height() - 0.02; // L = 51X // L length of barcode (excluding quite zone) in units same as X and I // X the width of a bar (pixels in our case) qreal L; qreal X = bar_width; L = (51.0 * X); // now we have the actual width the barcode will be so can determine the actual // size of the quiet zone (we assume we center the barcode in the given area // what should we do if the area is too small???? // At the moment the way the code is written is we will always start at the minimum // required quiet zone if we don't have enough space.... I guess we'll just have over-run // to the right // // calculate the starting position based on the alignment option // for left align we don't need to do anything as the values are already setup for it if(align == 1) // center { qreal nqz = (draw_width - L) / 2; if(nqz > quiet_zone) quiet_zone = nqz; } else if(align > 1) // right quiet_zone = draw_width - (L + quiet_zone); // else if(align < 1) {} // left : do nothing qreal pos = r.left() + quiet_zone; qreal top = r.top(); QPen pen(Qt::NoPen); QBrush brush(QColor("black")); int b = 0; int w = 0; // render open guard ORORect * rect = new ORORect(); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); page->addPrimitive(rect); pos += (bar_width * 2.0); rect = new ORORect(); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); page->addPrimitive(rect); pos += bar_width; // render first set for(i = 0; i < 6; i++) { b = val[i+1]; for(w = 0; w < 7; w++) { if(_encodings[b][_upcparenc[val[7]][val[0]][i]][w]) { rect = new ORORect(); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height - 0.07)); page->addPrimitive(rect); } pos += bar_width; } } // render center guard pos += bar_width; rect = new ORORect(); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); page->addPrimitive(rect); pos += (bar_width * 2.0); rect = new ORORect(); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); page->addPrimitive(rect); pos += (bar_width * 2.0); // render close guard rect = new ORORect(); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); page->addPrimitive(rect); QString parstr = QString("%1").arg(val[0]); QString chkstr = QString("%1").arg(val[7]); QString leftstr = QString().sprintf("%d%d%d%d%d%d", val[1], val[2], val[3], val[4], val[5], val[6]); QFont font("Arial",6); OROTextBox * tb = new OROTextBox(); tb->setPosition(QPointF(r.left(), r.top() + draw_height - 0.12)); tb->setSize(QSizeF(quiet_zone - 0.02, 0.12)); tb->setFont(font); tb->setText(parstr); tb->setFlags(Qt::AlignRight | Qt::AlignTop); page->addPrimitive(tb); tb = new OROTextBox(); tb->setPosition(QPointF(r.left() + quiet_zone + 0.03, (r.top() + draw_height) - 0.07)); tb->setSize(QSizeF(0.42, 0.10)); tb->setFont(font); tb->setText(leftstr); tb->setFlags(Qt::AlignHCenter | Qt::AlignTop); page->addPrimitive(tb); tb = new OROTextBox(); tb->setPosition(QPointF(r.left() + quiet_zone + L + 0.02, r.top() + draw_height - 0.12)); tb->setSize(QSizeF(0.08, 0.12)); tb->setFont(font); tb->setText(chkstr); tb->setFlags(Qt::AlignLeft | Qt::AlignTop); page->addPrimitive(tb); return; }