KReport

i2of5.cpp
1 /* This file is part of the KDE project
2  * Copyright (C) 2001-2012 by OpenMFG, LLC
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  * Please contact [email protected] with any questions on this license.
18  */
19 
20 /*
21  * This file contains the implementation of the interleaved 2 of 5 barcode renderer.
22  * All this code assumes a 100dpi rendering surface for it's calculations.
23  */
24 
25 #include <QString>
26 #include <QRectF>
27 #include <QPen>
28 #include <QBrush>
29 
30 #include "KReportRenderObjects.h"
31 
32 const char* _i2of5charmap[] = {
33  "NNWWN",
34  "WNNNW",
35  "NWNNW",
36  "WWNNN",
37  "NNWNW",
38  "WNWNN",
39  "NWWNN",
40  "NNNWW",
41  "WNNWN",
42  "NWNWN"
43 };
44 
45 
46 static QPointF addElement(OROPage * page, const QRectF &r, QPointF startPos, qreal width, bool isSpace)
47 {
48  QPen pen(Qt::NoPen);
49  QBrush brush(QColor("black"));
50 
51  if (!isSpace) {
52  ORORect * rect = new ORORect();
53  rect->setPen(pen);
54  rect->setBrush(brush);
55  rect->setRect(QRectF(startPos.x(),startPos.y(), width, r.height()));
56  //rect->setRotationAxis(bc->rect.topLeft()); //!< @todo check this
57  page->insertPrimitive(rect);
58  }
59  return QPointF(startPos.x() + width, startPos.y());
60 }
61 
62 static QPointF addBar(OROPage * page, const QRectF &r, QPointF startPos, qreal width)
63 {
64  return addElement(page, r, startPos, width, false);
65 }
66 static QPointF addSpace(OROPage * page, const QRectF &r, QPointF startPos, qreal width)
67 {
68  return addElement(page, r, startPos, width, true);
69 }
70 
71 
72 void renderI2of5(OROPage * page, const QRectF &r, const QString & _str, Qt::Alignment align)
73 {
74  QString str = _str;
75  qreal narrow_bar = 1; // a narrow bar is 1/100th inch wide
76  qreal bar_width_mult = 2.5; // the wide bar width multiple of the narrow bar
77  qreal wide_bar = narrow_bar * bar_width_mult;
78 
79  if (str.length() % 2) {
80  str = QLatin1Char('0') + str; // padding zero if number of characters is not even
81  }
82 
83  // this is our mandatory minimum quiet zone
84  qreal quiet_zone = narrow_bar * 10;
85  if (quiet_zone < 0.1) {
86  quiet_zone = 0.1;
87  }
88 
89  // what kind of area do we have to work with
90  qreal draw_width = r.width();
91 
92  // how long is the value we need to encode?
93  int val_length = str.length();
94 
95  // L = (C(2N+3)+6+N)X
96  // L length of barcode (excluding quite zone
97  // C the number of characters in the value excluding the start/stop
98  // N the bar width multiple for wide bars
99  // X the width of a bar (pixels in our case)
100  qreal L;
101  qreal C = val_length;
102  qreal N = bar_width_mult;
103  qreal X = narrow_bar;
104 
105  L = (C * (2.0*N + 3.0) + 6.0 + N) * X;
106 
107  // now we have the actual width the barcode will be so can determine the actual
108  // size of the quiet zone (we assume we center the barcode in the given area)
109  // At the moment the way the code is written is we will always start at the minimum
110  // required quiet zone if we don't have enough space.... I guess we'll just have over-run
111  // to the right
112  //
113  // calculate the starting position based on the alignment option
114  if (align == Qt::AlignHCenter) {
115  qreal nqz = (draw_width - L) / 2.0;
116  if (nqz > quiet_zone) {
117  quiet_zone = nqz;
118  }
119  }
120  else if (align == Qt::AlignRight) {
121  quiet_zone = draw_width - (L + quiet_zone);
122  }
123  // left : do nothing
124 
125  QPointF pos(r.left() + quiet_zone, r.top());
126 
127  // start character
128  pos = addBar(page, r, pos, narrow_bar);
129  pos = addSpace(page, r, pos, narrow_bar);
130  pos = addBar(page, r, pos, narrow_bar);
131  pos = addSpace(page, r, pos, narrow_bar);
132 
133  for (int i = 0; i < str.length()-1; i+=2) {
134  for (int iElt = 0; _i2of5charmap [0][iElt] != '\0'; iElt++) {
135  for (int offset=0; offset<=1; offset++) {
136  QChar c = str.at(i+offset);
137  if (!c.isDigit()) {
138  break; // invalid character
139  }
140 
141  int iChar = c.digitValue();
142  qreal width = _i2of5charmap[iChar][iElt] == 'W' ? wide_bar : narrow_bar;
143  pos = addElement(page, r, pos, width, offset==1);
144  }
145  }
146  }
147 
148  // stop character
149  pos = addBar(page, r, pos, wide_bar);
150  pos = addSpace(page, r, pos, narrow_bar);
151  pos = addBar(page, r, pos, narrow_bar);
152 }
qreal left() const const
typedef Alignment
bool isDigit() const const
Represents a single page in a document and may contain zero or more OROPrimitive objects all of which...
Defines a rectangle.
int length() const const
int digitValue() const const
qreal top() const const
qreal x() const const
qreal y() const const
qreal width() const const
const QChar at(int position) const const
qreal height() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:17:37 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.