KReport

i2of5paint.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 <QPainter>
28#include <QPen>
29#include <QBrush>
30
31const char* __i2of5charmap[] = {
32 "NNWWN",
33 "WNNNW",
34 "NWNNW",
35 "WWNNN",
36 "NNWNW",
37 "WNWNN",
38 "NWWNN",
39 "NNNWW",
40 "WNNWN",
41 "NWNWN"
42};
43
44
45static QPointF addElement(const QRectF &r, QPointF startPos, qreal width, bool isSpace, QPainter * pPainter)
46{
47 if (!isSpace && pPainter) {
48 pPainter->fillRect(startPos.x(),startPos.y(), width, r.height(), pPainter->pen().color());
49 }
50
51 return QPointF(startPos.x() + width, startPos.y());
52}
53
54static QPointF addBar(const QRectF &r, QPointF startPos, qreal width, QPainter * pPainter)
55{
56 return addElement(r, startPos, width, false, pPainter);
57}
58static QPointF addSpace(const QRectF &r, QPointF startPos, qreal width, QPainter * pPainter)
59{
60 return addElement(r, startPos, width, true, pPainter);
61}
62
63
64void renderI2of5(const QRectF &r, const QString & _str, Qt::Alignment align, QPainter * pPainter)
65{
66 QString str = _str;
67 qreal narrow_bar = 1; // a narrow bar is 1/100th inch wide
68 qreal bar_width_mult = 2.5; // the wide bar width multiple of the narrow bar
69 qreal wide_bar = narrow_bar * bar_width_mult;
70
71 if (str.length() % 2) {
72 str = QLatin1Char('0')+ str; // padding zero if number of characters is not even
73 }
74
75 // this is our mandatory minimum quiet zone
76 qreal quiet_zone = narrow_bar * 10;
77 if(quiet_zone < 0.1) {
78 quiet_zone = 0.1;
79 }
80
81 // what kind of area do we have to work with
82 int draw_width = r.width();
83
84 // how long is the value we need to encode?
85 int val_length = str.length();
86
87 // L = (C(2N+3)+6+N)X
88 // L length of barcode (excluding quite zone
89 // C the number of characters in the value excluding the start/stop
90 // N the bar width multiple for wide bars
91 // X the width of a bar (pixels in our case)
92 int L;
93 int C = val_length;
94 qreal N = bar_width_mult;
95 qreal X = narrow_bar;
96
97 L = (C * (2.0*N + 3.0) + 6.0 + N) * X;
98
99 // now we have the actual width the barcode will be so can determine the actual
100 // size of the quiet zone (we assume we center the barcode in the given area)
101 // At the moment the way the code is written is we will always start at the minimum
102 // required quiet zone if we don't have enough space.... I guess we'll just have over-run
103 // to the right
104 //
105 // calculate the starting position based on the alignment option
106 if (align == Qt::AlignHCenter) {
107 int nqz = (draw_width - L) / 2.0;
108 if (nqz > quiet_zone) {
109 quiet_zone = nqz;
110 }
111 }
112 else if (align == Qt::AlignRight) {
113 quiet_zone = draw_width - (L + quiet_zone);
114 }
115 // left : do nothing
116
117 if (pPainter) {
118 pPainter->save();
119
120 QPen oneWide(pPainter->pen());
121 oneWide.setWidth(1);
122#ifndef Q_OS_WIN32
123 oneWide.setJoinStyle(Qt::MiterJoin);
124#endif
125 pPainter->setPen(oneWide);
126 pPainter->setBrush(pPainter->pen().color());
127 }
128
129 QPointF pos(r.left() + quiet_zone, r.top());
130
131 // start character
132 pos = addBar(r, pos, narrow_bar,pPainter);
133 pos = addSpace(r, pos, narrow_bar, pPainter);
134 pos = addBar(r, pos, narrow_bar, pPainter);
135 pos = addSpace(r, pos, narrow_bar, pPainter);
136
137 for (int i = 0; i < str.length()-1; i+=2) {
138 for (int iElt = 0; __i2of5charmap [0][iElt] != '\0'; iElt++) {
139 for (int offset=0; offset<=1; offset++) {
140 QChar c = str.at(i+offset);
141 if (!c.isDigit()) {
142 break; // invalid character
143 }
144
145 int iChar = c.digitValue();
146 int width = __i2of5charmap[iChar][iElt] == 'W' ? wide_bar : narrow_bar;
147 pos = addElement(r, pos, width, offset==1, pPainter);
148 }
149 }
150 }
151
152 // stop character
153 pos = addBar(r, pos, wide_bar, pPainter);
154 pos = addSpace(r, pos, narrow_bar, pPainter);
155 pos = addBar(r, pos, narrow_bar, pPainter);
156}
int digitValue(char32_t ucs4)
bool isDigit(char32_t ucs4)
void fillRect(const QRect &rectangle, QGradient::Preset preset)
const QPen & pen() const const
void save()
void setBrush(Qt::BrushStyle style)
void setPen(Qt::PenStyle style)
QColor color() const const
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
MiterJoin
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.