void renderCodeEAN13(const QRect & r, const QString & _str, int align, QPainter * pPainter) { 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 int bar_width = 1; // the width of the base unit bar // this is are mandatory minimum quiet zone int quiet_zone = bar_width * 10; if(quiet_zone < 10) quiet_zone = 10; // what kind of area do we have to work with int draw_width = r.width(); int draw_height = r.height() - 2; // 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) int L; int X = bar_width; L = (95 * 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 int 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 int pos = r.left() + quiet_zone; int top = r.top(); if(pPainter != 0) { pPainter->save(); QPen oneWide(pPainter->pen()); oneWide.setWidth(1); #ifndef Q_WS_WIN32 oneWide.setJoinStyle(Qt::MiterJoin); #endif pPainter->setPen(oneWide); pPainter->setBrush(pPainter->pen().color()); int b = 0, w = 0; // render open guard pPainter->fillRect(pos,top, 1,draw_height, pPainter->pen().color()); pos += 2; pPainter->fillRect(pos,top, 1,draw_height, pPainter->pen().color()); pos ++; // 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]) { pPainter->fillRect(pos,top, 1,draw_height - 7, pPainter->pen().color()); } pos++; } } // render center guard pos++; pPainter->fillRect(pos,top, 1,draw_height, pPainter->pen().color()); pos += 2; pPainter->fillRect(pos,top, 1,draw_height, pPainter->pen().color()); pos += 2; // render last set for(i = 0; i < 6; i++) { b = val[i+7]; for(w = 0; w < 7; w++) { if(_encodings[b][RIGHTHAND][w]) { pPainter->fillRect(pos,top, 1,draw_height - 7, pPainter->pen().color()); } pos++; } } // render close guard pPainter->fillRect(pos,top, 1,draw_height, pPainter->pen().color()); pos += 2; pPainter->fillRect(pos,top, 1,draw_height, pPainter->pen().color()); 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]); pPainter->setFont(QFont("Arial",6)); pPainter->drawText(r.left(), r.top() + draw_height - 12, quiet_zone - 2, 12, Qt::AlignRight | Qt::AlignTop, parstr); pPainter->drawText(r.left() + quiet_zone + 3, (r.top() + draw_height) - 7, 42, 10, Qt::AlignHCenter | Qt::AlignTop, leftstr); pPainter->drawText(r.left() + quiet_zone + 50, (r.top() + draw_height) - 7, 42, 10, Qt::AlignHCenter | Qt::AlignTop, rightstr); pPainter->restore(); } return; }
void renderCode128(const QRect & r, const QString & _str, int align, QPainter * pPainter) { Q3ValueVector<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 int bar_width = 1; // the width of the base unit bar // this is are mandatory minimum quiet zone int quiet_zone = bar_width * 10; if(quiet_zone < 10) quiet_zone = 10; // what kind of area do we have to work with int draw_width = r.width(); int 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) int L; int C = val_length; int X = bar_width; L = (((11 * C) + 35) * 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 int 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 int pos = r.left() + quiet_zone; int top = r.top(); if(pPainter != 0) { pPainter->save(); QPen oneWide(pPainter->pen()); oneWide.setWidth(1); #ifndef Q_WS_WIN32 oneWide.setJoinStyle(Qt::MiterJoin); #endif pPainter->setPen(oneWide); pPainter->setBrush(pPainter->pen().color()); } bool space = false; int idx = 0, b = 0, w = 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 && pPainter != 0) { pPainter->fillRect(pos,top, w,draw_height, pPainter->pen().color()); } 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 && pPainter != 0) { pPainter->fillRect(pos,top, w,draw_height, pPainter->pen().color()); } pos += w; } if(pPainter != 0) { pPainter->restore(); } return; }
void render3of9(const QRect & r, const QString & _str, int align, QPainter * pPainter) { QString str = _str; // lets determine some core attributes about this barcode int narrow_bar = 1; // a narrow bar is 1px wide int 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 are mandatory minimum quiet zone int quiet_zone = narrow_bar * 10; if (quiet_zone < 10) quiet_zone = 10; // what kind of area do we have to work with int draw_width = r.width(); int 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) int L; int C = val_length; int N = bar_width_mult; int X = narrow_bar; int I = interchange_gap; L = ((C + 2) * (3 * N + 6) * X) + ((C + 1) * 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 (align == 1) { // center int 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 int pos = r.left() + quiet_zone; int top = r.top(); // ok we need to prepend and append the str with a * str = '*' + str + '*'; if (pPainter) { pPainter->save(); QPen oneWide(pPainter->pen()); oneWide.setWidth(1); #ifndef Q_OS_WIN32 oneWide.setJoinStyle(Qt::MiterJoin); #endif pPainter->setPen(oneWide); pPainter->setBrush(pPainter->pen().color()); } for (int i = 0; i < str.length(); i++) { // loop through each char and render the barcode QChar c = str.at(i); int idx = codeIndexP(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) { int w = (_3of9codes[idx].values[b] == 1 ? narrow_bar * bar_width_mult : narrow_bar); if (!space && pPainter) { pPainter->fillRect(pos, top, w, draw_height, pPainter->pen().color()); } pos += w; } pos += interchange_gap; } if (pPainter) { pPainter->restore(); } }