Example #1
0
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;
} 
Example #2
0
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;
} 
Example #3
0
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();
    }
}