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 info@openmfg.com 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
32const 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
46static 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
62static QPointF addBar(OROPage * page, const QRectF &r, QPointF startPos, qreal width)
63{
64 return addElement(page, r, startPos, width, false);
65}
66static QPointF addSpace(OROPage * page, const QRectF &r, QPointF startPos, qreal width)
67{
68 return addElement(page, r, startPos, width, true);
69}
70
71
72void 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}
Represents a single page in a document and may contain zero or more OROPrimitive objects all of which...
Defines a rectangle.
int digitValue(char32_t ucs4)
bool isDigit(char32_t ucs4)
qreal x() const const
qreal y() const const
qreal height() const const
qreal left() const const
qreal top() const const
qreal width() const const
const QChar at(qsizetype position) const const
qsizetype length() const const
typedef Alignment
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:21:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.