File indexing completed on 2024-05-12 04:43:19
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com) 0003 * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2.1 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public 0016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 /* 0020 * This file contains the implementation of the Code EAN and similar 0021 * formats for rendering purposes. All this code assumes a 100dpi 0022 * rendering surface for it's calculations. 0023 */ 0024 0025 #include <QString> 0026 #include <QRect> 0027 #include <QPainter> 0028 #include <QPen> 0029 #include <QBrush> 0030 0031 #include "KReportRenderObjects.h" 0032 0033 static const int LEFTHAND_ODD = 0; 0034 static const int LEFTHAND_EVEN = 1; 0035 static const int RIGHTHAND = 2; 0036 0037 static int const _encodings[10][3][7] = { 0038 /* LEFTHAND_ODD */ /* LEFTHAND_EVEN */ /* RIGHTHAND */ 0039 { { 0, 0, 0, 1, 1, 0, 1}, { 0, 1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0 } }, // 0 0040 { { 0, 0, 1, 1, 0, 0, 1}, { 0, 1, 1, 0, 0, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0 } }, // 1 0041 { { 0, 0, 1, 0, 0, 1, 1}, { 0, 0, 1, 1, 0, 1, 1 }, { 1, 1, 0, 1, 1, 0, 0 } }, // 2 0042 { { 0, 1, 1, 1, 1, 0, 1}, { 0, 1, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 1, 0 } }, // 3 0043 { { 0, 1, 0, 0, 0, 1, 1}, { 0, 0, 1, 1, 1, 0, 1 }, { 1, 0, 1, 1, 1, 0, 0 } }, // 4 0044 { { 0, 1, 1, 0, 0, 0, 1}, { 0, 1, 1, 1, 0, 0, 1 }, { 1, 0, 0, 1, 1, 1, 0 } }, // 5 0045 { { 0, 1, 0, 1, 1, 1, 1}, { 0, 0, 0, 0, 1, 0, 1 }, { 1, 0, 1, 0, 0, 0, 0 } }, // 6 0046 { { 0, 1, 1, 1, 0, 1, 1}, { 0, 0, 1, 0, 0, 0, 1 }, { 1, 0, 0, 0, 1, 0, 0 } }, // 7 0047 { { 0, 1, 1, 0, 1, 1, 1}, { 0, 0, 0, 1, 0, 0, 1 }, { 1, 0, 0, 1, 0, 0, 0 } }, // 8 0048 { { 0, 0, 0, 1, 0, 1, 1}, { 0, 0, 1, 0, 1, 1, 1 }, { 1, 1, 1, 0, 1, 0, 0 } } // 9 0049 }; 0050 0051 static const int odd = LEFTHAND_ODD; 0052 static const int even = LEFTHAND_EVEN; 0053 0054 static const int _parity[10][6] = { 0055 { odd, odd, odd, odd, odd, odd }, // 0 0056 { odd, odd, even, odd, even, even }, // 1 0057 { odd, odd, even, even, odd, even }, // 2 0058 { odd, odd, even, even, even, odd }, // 3 0059 { odd, even, odd, odd, even, even }, // 4 0060 { odd, even, even, odd, odd, even }, // 5 0061 { odd, even, even, even, odd, odd }, // 6 0062 { odd, even, odd, even, odd, even }, // 7 0063 { odd, even, odd, even, even, odd }, // 8 0064 { odd, even, even, odd, even, odd } // 9 0065 }; 0066 0067 static const int _upcparenc[10][2][6] = { 0068 /* PARITY 0 */ /* PARITY 1 */ 0069 { { even, even, even, odd, odd, odd }, { odd, odd, odd, even, even, even } }, // 0 0070 { { even, even, odd, even, odd, odd }, { odd, odd, even, odd, even, even } }, // 1 0071 { { even, even, odd, odd, even, odd }, { odd, odd, even, even, odd, even } }, // 2 0072 { { even, even, odd, odd, odd, even }, { odd, odd, even, even, even, odd } }, // 3 0073 { { even, odd, even, even, odd, odd }, { odd, even, odd, odd, even, even } }, // 4 0074 { { even, odd, odd, even, even, odd }, { odd, even, even, odd, odd, even } }, // 5 0075 { { even, odd, odd, odd, even, even }, { odd, even, even, even, odd, odd } }, // 6 0076 { { even, odd, even, odd, even, odd }, { odd, even, odd, even, odd, even } }, // 7 0077 { { even, odd, even, odd, odd, even }, { odd, even, odd, even, even, odd } }, // 8 0078 { { even, odd, odd, even, odd, even }, { odd, even, even, odd, even, odd } } // 9 0079 }; 0080 0081 0082 void renderCodeEAN13(const QRect & r, const QString & _str, Qt::Alignment align, QPainter * pPainter) 0083 { 0084 int val[13]; 0085 0086 // initialize all the values just so we can be predictable 0087 for (int i = 0; i < 13; ++i) { 0088 val[i] = -1; 0089 } 0090 0091 // verify that the passed in string is valid 0092 // if it's not either twelve or thirteen characters 0093 // then it must be invalid to begin with 0094 if (_str.length() != 12 && _str.length() != 13) return; 0095 // loop through and convert each char to a digit. 0096 // if we can't convert all characters then this is 0097 // an invalid number 0098 for (int i = 0; i < _str.length(); ++i) { 0099 val[i] = ((QChar) _str.at(i)).digitValue(); 0100 if (val[i] == -1) return; 0101 } 0102 0103 // calculate and append the checksum value 0104 int old_sum = val[12]; // get the old check sum value (-1 if none was set) 0105 int checksum = 0; 0106 for (int i = 0; i < 12; ++i) { 0107 checksum += val[i] * ((i % 2) ? 3 : 1); 0108 } 0109 checksum = (checksum % 10); 0110 if (checksum) checksum = 10 - checksum; 0111 val[12] = checksum; 0112 0113 // if we had an old checksum value and if it doesn't match what we came 0114 // up with then the string must be invalid so we will bail 0115 if (old_sum != -1 && old_sum != checksum) return; 0116 0117 0118 // lets determine some core attributes about this barcode 0119 int bar_width = 1; // the width of the base unit bar 0120 0121 // this is are mandatory minimum quiet zone 0122 int quiet_zone = bar_width * 10; 0123 //if (quiet_zone < 10) quiet_zone = 10; 0124 0125 // what kind of area do we have to work with 0126 int draw_width = r.width(); 0127 int draw_height = r.height() - 2; 0128 0129 // L = 95X 0130 // L length of barcode (excluding quite zone) in units same as X and I 0131 // X the width of a bar (pixels in our case) 0132 int L; 0133 0134 int X = bar_width; 0135 0136 L = (95 * X); 0137 0138 // now we have the actual width the barcode will be so can determine the actual 0139 // size of the quiet zone (we assume we center the barcode in the given area 0140 // what should we do if the area is too small???? 0141 // At the moment the way the code is written is we will always start at the minimum 0142 // required quiet zone if we don't have enough space.... I guess we'll just have over-run 0143 // to the right 0144 // 0145 // calculate the starting position based on the alignment option 0146 // for left align we don't need to do anything as the values are already setup for it 0147 if (align == Qt::AlignHCenter) { 0148 int nqz = (draw_width - L) / 2; 0149 if (nqz > quiet_zone) quiet_zone = nqz; 0150 } else if (align == Qt::AlignRight) { 0151 quiet_zone = draw_width - (L + quiet_zone); 0152 } 0153 // left : do nothing 0154 0155 int pos = r.left() + quiet_zone; 0156 int top = r.top(); 0157 0158 if (pPainter) { 0159 pPainter->save(); 0160 0161 QPen oneWide(pPainter->pen()); 0162 oneWide.setWidth(1); 0163 #ifndef Q_OS_WIN32 0164 oneWide.setJoinStyle(Qt::MiterJoin); 0165 #endif 0166 pPainter->setPen(oneWide); 0167 pPainter->setBrush(pPainter->pen().color()); 0168 0169 // render open guard 0170 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0171 pos += 2; 0172 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0173 pos ++; 0174 0175 // render first set 0176 for (int i = 0; i < 6; ++i) { 0177 int b = val[i+1]; 0178 for (int w = 0; w < 7; ++w) { 0179 if (_encodings[b][_parity[val[0]][i]][w]) { 0180 pPainter->fillRect(pos, top, 1, draw_height - 7, pPainter->pen().color()); 0181 } 0182 pos++; 0183 } 0184 } 0185 0186 // render center guard 0187 pos++; 0188 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0189 pos += 2; 0190 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0191 pos += 2; 0192 0193 // render last set 0194 for (int i = 0; i < 6; ++i) { 0195 int b = val[i+7]; 0196 for (int w = 0; w < 7; ++w) { 0197 if (_encodings[b][RIGHTHAND][w]) { 0198 pPainter->fillRect(pos, top, 1, draw_height - 7, pPainter->pen().color()); 0199 } 0200 pos++; 0201 } 0202 } 0203 0204 // render close guard 0205 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0206 pos += 2; 0207 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0208 0209 QString parstr = QString::number(val[0]); 0210 QString leftstr = QString::asprintf("%d%d%d%d%d%d", 0211 val[1], val[2], val[3], val[4], val[5], val[6]); 0212 QString rightstr = QString::asprintf("%d%d%d%d%d%d", 0213 val[7], val[8], val[9], val[10], val[11], val[12]); 0214 pPainter->setFont(QFont(QLatin1String("Arial"), 6)); 0215 pPainter->drawText(r.left(), r.top() + draw_height - 12, 0216 quiet_zone - 2, 12, Qt::AlignRight | Qt::AlignTop, 0217 parstr); 0218 pPainter->drawText(r.left() + quiet_zone + 3, 0219 (r.top() + draw_height) - 7, 0220 42, 10, Qt::AlignHCenter | Qt::AlignTop, 0221 leftstr); 0222 pPainter->drawText(r.left() + quiet_zone + 50, 0223 (r.top() + draw_height) - 7, 0224 42, 10, Qt::AlignHCenter | Qt::AlignTop, 0225 rightstr); 0226 0227 pPainter->restore(); 0228 } 0229 } 0230 0231 void renderCodeUPCA(const QRect & r, const QString & _str, Qt::Alignment align, QPainter * pPainter) 0232 { 0233 int val[13]; 0234 0235 // initialize all the values just so we can be predictable 0236 for (int i = 0; i < 13; ++i) { 0237 val[i] = -1; 0238 } 0239 0240 // verify that the passed in string is valid 0241 // if it's not either twelve or thirteen characters 0242 // then it must be invalid to begin with 0243 if (_str.length() != 11 && _str.length() != 12) return; 0244 // loop through and convert each char to a digit. 0245 // if we can't convert all characters then this is 0246 // an invalid number 0247 val[0] = 0; 0248 for (int i = 0; i < _str.length(); ++i) { 0249 val[i+1] = ((QChar) _str.at(i)).digitValue(); 0250 if (val[i+1] == -1) return; 0251 } 0252 0253 // calculate and append the checksum value 0254 int old_sum = val[12]; // get the old check sum value (-1 if none was set) 0255 int checksum = 0; 0256 for (int i = 0; i < 12; ++i) { 0257 checksum += val[i] * ((i % 2) ? 3 : 1); 0258 } 0259 checksum = (checksum % 10); 0260 if (checksum) checksum = 10 - checksum; 0261 val[12] = checksum; 0262 0263 // if we had an old checksum value and if it doesn't match what we came 0264 // up with then the string must be invalid so we will bail 0265 if (old_sum != -1 && old_sum != checksum) return; 0266 0267 0268 // lets determine some core attributes about this barcode 0269 int bar_width = 1; // the width of the base unit bar 0270 0271 // this is are mandatory minimum quiet zone 0272 int quiet_zone = bar_width * 10; 0273 //if (quiet_zone < 10) quiet_zone = 10; 0274 0275 // what kind of area do we have to work with 0276 int draw_width = r.width(); 0277 int draw_height = r.height() - 2; 0278 0279 // L = 95X 0280 // L length of barcode (excluding quite zone) in units same as X and I 0281 // X the width of a bar (pixels in our case) 0282 int L; 0283 0284 int X = bar_width; 0285 0286 L = (95 * X); 0287 0288 // now we have the actual width the barcode will be so can determine the actual 0289 // size of the quiet zone (we assume we center the barcode in the given area 0290 // what should we do if the area is too small???? 0291 // At the moment the way the code is written is we will always start at the minimum 0292 // required quiet zone if we don't have enough space.... I guess we'll just have over-run 0293 // to the right 0294 // 0295 // calculate the starting position based on the alignment option 0296 // for left align we don't need to do anything as the values are already setup for it 0297 if (align == Qt::AlignHCenter) { 0298 int nqz = (draw_width - L) / 2; 0299 if (nqz > quiet_zone) quiet_zone = nqz; 0300 } else if (align == Qt::AlignRight) { 0301 quiet_zone = draw_width - (L + quiet_zone); 0302 } 0303 // left : do nothing 0304 0305 int pos = r.left() + quiet_zone; 0306 int top = r.top(); 0307 0308 if (pPainter) { 0309 pPainter->save(); 0310 0311 QPen oneWide(pPainter->pen()); 0312 oneWide.setWidth(1); 0313 #ifndef Q_OS_WIN32 0314 oneWide.setJoinStyle(Qt::MiterJoin); 0315 #endif 0316 pPainter->setPen(oneWide); 0317 pPainter->setBrush(pPainter->pen().color()); 0318 0319 // render open guard 0320 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0321 pos += 2; 0322 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0323 pos ++; 0324 0325 // render first set 0326 for (int i = 0; i < 6; ++i) { 0327 int b = val[i+1]; 0328 for (int w = 0; w < 7; ++w) { 0329 if (_encodings[b][_parity[val[0]][i]][w]) { 0330 pPainter->fillRect(pos, top, 1, draw_height - (i == 0 ? 0 : 7), pPainter->pen().color()); 0331 } 0332 pos++; 0333 } 0334 } 0335 0336 // render center guard 0337 pos++; 0338 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0339 pos += 2; 0340 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0341 pos += 2; 0342 0343 // render last set 0344 for (int i = 0; i < 6; ++i) { 0345 int b = val[i+7]; 0346 for (int w = 0; w < 7; ++w) { 0347 if (_encodings[b][RIGHTHAND][w]) { 0348 pPainter->fillRect(pos, top, 1, draw_height - (i == 5 ? 0 : 7), pPainter->pen().color()); 0349 } 0350 pos++; 0351 } 0352 } 0353 0354 // render close guard 0355 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0356 pos += 2; 0357 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0358 0359 QString parstr = QString::number(val[1]); 0360 QString chkstr = QString::number(val[12]); 0361 QString leftstr = QString().sprintf("%d%d%d%d%d", 0362 val[2], val[3], val[4], val[5], val[6]); 0363 QString rightstr = QString().sprintf("%d%d%d%d%d", 0364 val[7], val[8], val[9], val[10], val[11]); 0365 pPainter->setFont(QFont(QLatin1String("Arial"), 6)); 0366 pPainter->drawText(r.left(), r.top() + draw_height - 12, 0367 quiet_zone - 2, 12, Qt::AlignRight | Qt::AlignTop, 0368 parstr); 0369 pPainter->drawText(r.left() + quiet_zone + 10, 0370 (r.top() + draw_height) - 7, 0371 35, 10, Qt::AlignHCenter | Qt::AlignTop, 0372 leftstr); 0373 pPainter->drawText(r.left() + quiet_zone + 50, 0374 (r.top() + draw_height) - 7, 0375 35, 10, Qt::AlignHCenter | Qt::AlignTop, 0376 rightstr); 0377 pPainter->drawText(r.left() + quiet_zone + L + 2, r.top() + draw_height - 12, 0378 8, 12, Qt::AlignLeft | Qt::AlignTop, 0379 chkstr); 0380 0381 pPainter->restore(); 0382 } 0383 } 0384 0385 void renderCodeEAN8(const QRect & r, const QString & _str, Qt::Alignment align, QPainter * pPainter) 0386 { 0387 int val[8]; 0388 0389 // initialize all the values just so we can be predictable 0390 for (int i = 0; i < 8; ++i) { 0391 val[i] = -1; 0392 } 0393 0394 // verify that the passed in string is valid 0395 // if it's not either twelve or thirteen characters 0396 // then it must be invalid to begin with 0397 if (_str.length() != 7 && _str.length() != 8) return; 0398 // loop through and convert each char to a digit. 0399 // if we can't convert all characters then this is 0400 // an invalid number 0401 for (int i = 0; i < _str.length(); ++i) { 0402 val[i] = ((QChar) _str.at(i)).digitValue(); 0403 if (val[i] == -1) return; 0404 } 0405 0406 // calculate and append the checksum value 0407 int old_sum = val[7]; // get the old check sum value (-1 if none was set) 0408 int checksum = 0; 0409 for (int i = 0; i < 7; ++i) { 0410 checksum += val[i] * ((i % 2) ? 1 : 3); 0411 } 0412 checksum = (checksum % 10); 0413 if (checksum) checksum = 10 - checksum; 0414 val[7] = checksum; 0415 0416 // if we had an old checksum value and if it doesn't match what we came 0417 // up with then the string must be invalid so we will bail 0418 if (old_sum != -1 && old_sum != checksum) return; 0419 0420 0421 // lets determine some core attributes about this barcode 0422 int bar_width = 1; // the width of the base unit bar 0423 0424 // this is are mandatory minimum quiet zone 0425 int quiet_zone = bar_width * 10; 0426 //if (quiet_zone < 10) quiet_zone = 10; 0427 0428 // what kind of area do we have to work with 0429 int draw_width = r.width(); 0430 int draw_height = r.height() - 2; 0431 0432 // L = 60X 0433 // L length of barcode (excluding quite zone) in units same as X and I 0434 // X the width of a bar (pixels in our case) 0435 int L; 0436 0437 int X = bar_width; 0438 0439 L = (67 * X); 0440 0441 // now we have the actual width the barcode will be so can determine the actual 0442 // size of the quiet zone (we assume we center the barcode in the given area 0443 // what should we do if the area is too small???? 0444 // At the moment the way the code is written is we will always start at the minimum 0445 // required quiet zone if we don't have enough space.... I guess we'll just have over-run 0446 // to the right 0447 // 0448 // calculate the starting position based on the alignment option 0449 // for left align we don't need to do anything as the values are already setup for it 0450 if (align == Qt::AlignHCenter) { 0451 int nqz = (draw_width - L) / 2; 0452 if (nqz > quiet_zone) quiet_zone = nqz; 0453 } else if (align == Qt::AlignRight) { 0454 quiet_zone = draw_width - (L + quiet_zone); 0455 } 0456 // left : do nothing 0457 0458 int pos = r.left() + quiet_zone; 0459 int top = r.top(); 0460 0461 if (pPainter) { 0462 pPainter->save(); 0463 0464 QPen oneWide(pPainter->pen()); 0465 oneWide.setWidth(1); 0466 #ifndef Q_OS_WIN32 0467 oneWide.setJoinStyle(Qt::MiterJoin); 0468 #endif 0469 pPainter->setPen(oneWide); 0470 pPainter->setBrush(pPainter->pen().color()); 0471 0472 // render open guard 0473 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0474 pos += 2; 0475 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0476 pos ++; 0477 0478 // render first set 0479 for (int i = 0; i < 4; ++i) { 0480 int b = val[i]; 0481 for (int w = 0; w < 7; ++w) { 0482 if (_encodings[b][LEFTHAND_ODD][w]) { 0483 pPainter->fillRect(pos, top, 1, draw_height - 6, pPainter->pen().color()); 0484 } 0485 pos++; 0486 } 0487 } 0488 0489 // render center guard 0490 pos++; 0491 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0492 pos += 2; 0493 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0494 pos += 2; 0495 0496 // render last set 0497 for (int i = 0; i < 4; ++i) { 0498 int b = val[i+4]; 0499 for (int w = 0; w < 7; ++w) { 0500 if (_encodings[b][RIGHTHAND][w]) { 0501 pPainter->fillRect(pos, top, 1, draw_height - 6, pPainter->pen().color()); 0502 } 0503 pos++; 0504 } 0505 } 0506 0507 // render close guard 0508 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0509 pos += 2; 0510 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0511 0512 QString leftstr = QString().sprintf("%d%d%d%d", 0513 val[0], val[1], val[2], val[3]); 0514 QString rightstr = QString().sprintf("%d%d%d%d", 0515 val[4], val[5], val[6], val[7]); 0516 pPainter->setFont(QFont(QLatin1String("Arial"), 6)); 0517 pPainter->drawText(r.left() + quiet_zone + 3, 0518 (r.top() + draw_height) - 6, 0519 28, 10, Qt::AlignHCenter | Qt::AlignTop, 0520 leftstr); 0521 pPainter->drawText(r.left() + quiet_zone + 36, 0522 (r.top() + draw_height) - 6, 0523 28, 10, Qt::AlignHCenter | Qt::AlignTop, 0524 rightstr); 0525 0526 pPainter->restore(); 0527 } 0528 } 0529 0530 void renderCodeUPCE(const QRect & r, const QString & _str, Qt::Alignment align, QPainter * pPainter) 0531 { 0532 int val[8]; 0533 0534 // initialize all the values just so we can be predictable 0535 for (int i = 0; i < 8; ++i) { 0536 val[i] = -1; 0537 } 0538 0539 // verify that the passed in string is valid 0540 // if it's not either twelve or thirteen characters 0541 // then it must be invalid to begin with 0542 if (_str.length() != 8) return; 0543 // loop through and convert each char to a digit. 0544 // if we can't convert all characters then this is 0545 // an invalid number 0546 for (int i = 0; i < _str.length(); ++i) { 0547 val[i] = ((QChar) _str.at(i)).digitValue(); 0548 if (val[i] == -1) return; 0549 } 0550 0551 // calculate and append the checksum value 0552 // because everything is so messed up we don't calculate 0553 // the checksum and require that it be passed in already 0554 // however we do have to verify that the first digit is 0555 // either 0 or 1 as that is our parity 0556 if (val[0] != 0 && val[0] != 1) return; 0557 0558 // lets determine some core attributes about this barcode 0559 int bar_width = 1; // the width of the base unit bar 0560 0561 // this is are mandatory minimum quiet zone 0562 int quiet_zone = bar_width * 10; 0563 //if (quiet_zone < 10) quiet_zone = 10; 0564 0565 // what kind of area do we have to work with 0566 int draw_width = r.width(); 0567 int draw_height = r.height() - 2; 0568 0569 // L = 51X 0570 // L length of barcode (excluding quite zone) in units same as X and I 0571 // X the width of a bar (pixels in our case) 0572 int L; 0573 0574 int X = bar_width; 0575 0576 L = (51 * X); 0577 0578 // now we have the actual width the barcode will be so can determine the actual 0579 // size of the quiet zone (we assume we center the barcode in the given area 0580 // what should we do if the area is too small???? 0581 // At the moment the way the code is written is we will always start at the minimum 0582 // required quiet zone if we don't have enough space.... I guess we'll just have over-run 0583 // to the right 0584 // 0585 // calculate the starting position based on the alignment option 0586 // for left align we don't need to do anything as the values are already setup for it 0587 if (align == Qt::AlignHCenter) { 0588 int nqz = (draw_width - L) / 2; 0589 if (nqz > quiet_zone) quiet_zone = nqz; 0590 } else if (align == Qt::AlignRight) { 0591 quiet_zone = draw_width - (L + quiet_zone); 0592 } 0593 // left : do nothing 0594 0595 int pos = r.left() + quiet_zone; 0596 int top = r.top(); 0597 0598 if (pPainter) { 0599 pPainter->save(); 0600 0601 QPen oneWide(pPainter->pen()); 0602 oneWide.setWidth(1); 0603 #ifndef Q_OS_WIN32 0604 oneWide.setJoinStyle(Qt::MiterJoin); 0605 #endif 0606 pPainter->setPen(oneWide); 0607 pPainter->setBrush(pPainter->pen().color()); 0608 0609 // render open guard 0610 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0611 pos += 2; 0612 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0613 pos ++; 0614 0615 // render first set 0616 for (int i = 0; i < 6; ++i) { 0617 int b = val[i+1]; 0618 for (int w = 0; w < 7; ++w) { 0619 if (_encodings[b][_upcparenc[val[7]][val[0]][i]][w]) { 0620 pPainter->fillRect(pos, top, 1, draw_height - 7, pPainter->pen().color()); 0621 } 0622 pos++; 0623 } 0624 } 0625 0626 // render center guard 0627 pos++; 0628 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0629 pos += 2; 0630 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0631 pos += 2; 0632 0633 // render close guard 0634 pPainter->fillRect(pos, top, 1, draw_height, pPainter->pen().color()); 0635 0636 QString parstr = QString::number(val[0]); 0637 QString chkstr = QString::number(val[7]); 0638 QString leftstr = QString().sprintf("%d%d%d%d%d%d", 0639 val[1], val[2], val[3], val[4], val[5], val[6]); 0640 pPainter->setFont(QFont(QLatin1String("Arial"), 6)); 0641 pPainter->drawText(r.left(), r.top() + draw_height - 12, 0642 quiet_zone - 2, 12, Qt::AlignRight | Qt::AlignTop, 0643 parstr); 0644 pPainter->drawText(r.left() + quiet_zone + 3, 0645 (r.top() + draw_height) - 7, 0646 42, 10, Qt::AlignHCenter | Qt::AlignTop, 0647 leftstr); 0648 pPainter->drawText(r.left() + quiet_zone + L + 2, r.top() + draw_height - 12, 0649 8, 12, Qt::AlignLeft | Qt::AlignTop, 0650 chkstr); 0651 0652 pPainter->restore(); 0653 } 0654 } 0655