File indexing completed on 2024-05-12 04:43:19
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2001-2012 by OpenMFG, LLC 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public 0015 * License along with this library; if not, write to the Free Software 0016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 0017 * Please contact info@openmfg.com with any questions on this license. 0018 */ 0019 0020 /* 0021 * This file contains the implementation of the interleaved 2 of 5 barcode renderer. 0022 * All this code assumes a 100dpi rendering surface for it's calculations. 0023 */ 0024 0025 #include <QString> 0026 #include <QRectF> 0027 #include <QPen> 0028 #include <QBrush> 0029 0030 #include "KReportRenderObjects.h" 0031 0032 const char* _i2of5charmap[] = { 0033 "NNWWN", 0034 "WNNNW", 0035 "NWNNW", 0036 "WWNNN", 0037 "NNWNW", 0038 "WNWNN", 0039 "NWWNN", 0040 "NNNWW", 0041 "WNNWN", 0042 "NWNWN" 0043 }; 0044 0045 0046 static QPointF addElement(OROPage * page, const QRectF &r, QPointF startPos, qreal width, bool isSpace) 0047 { 0048 QPen pen(Qt::NoPen); 0049 QBrush brush(QColor("black")); 0050 0051 if (!isSpace) { 0052 ORORect * rect = new ORORect(); 0053 rect->setPen(pen); 0054 rect->setBrush(brush); 0055 rect->setRect(QRectF(startPos.x(),startPos.y(), width, r.height())); 0056 //rect->setRotationAxis(bc->rect.topLeft()); //!< @todo check this 0057 page->insertPrimitive(rect); 0058 } 0059 return QPointF(startPos.x() + width, startPos.y()); 0060 } 0061 0062 static QPointF addBar(OROPage * page, const QRectF &r, QPointF startPos, qreal width) 0063 { 0064 return addElement(page, r, startPos, width, false); 0065 } 0066 static QPointF addSpace(OROPage * page, const QRectF &r, QPointF startPos, qreal width) 0067 { 0068 return addElement(page, r, startPos, width, true); 0069 } 0070 0071 0072 void renderI2of5(OROPage * page, const QRectF &r, const QString & _str, Qt::Alignment align) 0073 { 0074 QString str = _str; 0075 qreal narrow_bar = 1; // a narrow bar is 1/100th inch wide 0076 qreal bar_width_mult = 2.5; // the wide bar width multiple of the narrow bar 0077 qreal wide_bar = narrow_bar * bar_width_mult; 0078 0079 if (str.length() % 2) { 0080 str = QLatin1Char('0') + str; // padding zero if number of characters is not even 0081 } 0082 0083 // this is our mandatory minimum quiet zone 0084 qreal quiet_zone = narrow_bar * 10; 0085 if (quiet_zone < 0.1) { 0086 quiet_zone = 0.1; 0087 } 0088 0089 // what kind of area do we have to work with 0090 qreal draw_width = r.width(); 0091 0092 // how long is the value we need to encode? 0093 int val_length = str.length(); 0094 0095 // L = (C(2N+3)+6+N)X 0096 // L length of barcode (excluding quite zone 0097 // C the number of characters in the value excluding the start/stop 0098 // N the bar width multiple for wide bars 0099 // X the width of a bar (pixels in our case) 0100 qreal L; 0101 qreal C = val_length; 0102 qreal N = bar_width_mult; 0103 qreal X = narrow_bar; 0104 0105 L = (C * (2.0*N + 3.0) + 6.0 + N) * X; 0106 0107 // now we have the actual width the barcode will be so can determine the actual 0108 // size of the quiet zone (we assume we center the barcode in the given area) 0109 // At the moment the way the code is written is we will always start at the minimum 0110 // required quiet zone if we don't have enough space.... I guess we'll just have over-run 0111 // to the right 0112 // 0113 // calculate the starting position based on the alignment option 0114 if (align == Qt::AlignHCenter) { 0115 qreal nqz = (draw_width - L) / 2.0; 0116 if (nqz > quiet_zone) { 0117 quiet_zone = nqz; 0118 } 0119 } 0120 else if (align == Qt::AlignRight) { 0121 quiet_zone = draw_width - (L + quiet_zone); 0122 } 0123 // left : do nothing 0124 0125 QPointF pos(r.left() + quiet_zone, r.top()); 0126 0127 // start character 0128 pos = addBar(page, r, pos, narrow_bar); 0129 pos = addSpace(page, r, pos, narrow_bar); 0130 pos = addBar(page, r, pos, narrow_bar); 0131 pos = addSpace(page, r, pos, narrow_bar); 0132 0133 for (int i = 0; i < str.length()-1; i+=2) { 0134 for (int iElt = 0; _i2of5charmap [0][iElt] != '\0'; iElt++) { 0135 for (int offset=0; offset<=1; offset++) { 0136 QChar c = str.at(i+offset); 0137 if (!c.isDigit()) { 0138 break; // invalid character 0139 } 0140 0141 int iChar = c.digitValue(); 0142 qreal width = _i2of5charmap[iChar][iElt] == 'W' ? wide_bar : narrow_bar; 0143 pos = addElement(page, r, pos, width, offset==1); 0144 } 0145 } 0146 } 0147 0148 // stop character 0149 pos = addBar(page, r, pos, wide_bar); 0150 pos = addSpace(page, r, pos, narrow_bar); 0151 pos = addBar(page, r, pos, narrow_bar); 0152 }