1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "printout.h"
5
6#include <QPrinter>
7#include <QFontMetrics>
8
9QT_BEGIN_NAMESPACE
10
11using namespace Qt::StringLiterals;
12
13PrintOut::PrintOut(QPrinter *printer)
14 : pr(printer), nextRule(NoRule), page(0)
15{
16 p.begin(pr);
17 QFont f(QStringList{u"Arial"_s});
18 f8 = f;
19 f8.setPointSize(8);
20 f10 = f;
21 f10.setPointSize(10);
22 p.setFont(f10);
23 fmetrics = new QFontMetrics(p.fontMetrics());
24 hmargin = 5 * printer->width() / printer->widthMM(); // 5 mm
25 vmargin = 5 * printer->height() / printer->heightMM(); // 5 mm
26 hsize = printer->width() - 2 * hmargin;
27 vsize = printer->height() - vmargin;
28 dateTime = QDateTime::currentDateTime();
29 breakPage(init: true); // init vsize and draw first header
30 cp = Paragraph(QPoint(hmargin, voffset));
31}
32
33PrintOut::~PrintOut()
34{
35 flushLine();
36 delete fmetrics;
37 p.end();
38}
39
40void PrintOut::setRule(Rule rule)
41{
42 if (nextRule < rule)
43 nextRule = rule;
44}
45
46void PrintOut::setGuide(const QString &guide)
47{
48 g = guide;
49}
50
51void PrintOut::vskip()
52{
53 if (!firstParagraph)
54 voffset += 14;
55}
56
57void PrintOut::flushLine(bool /* mayBreak */)
58{
59 if (voffset + cp.rect.height() > vsize)
60 breakPage();
61 else if (!firstParagraph)
62 drawRule(rule: nextRule);
63
64 for (int i = 0; i < cp.boxes.size(); ++i) {
65 Box b = cp.boxes[i];
66 b.rect.translate(dx: 0, dy: voffset);
67 QRect r = b.rect;
68 p.setFont(b.font);
69 p.drawText(r, text: b.text, o: b.options);
70 }
71 voffset += cp.rect.height();
72
73 nextRule = NoRule;
74 cp = Paragraph(QPoint(hmargin, voffset));
75 firstParagraph = false;
76}
77
78void PrintOut::addBox(int percent, const QString &text, Style style, Qt::Alignment halign)
79{
80 QTextOption options;
81 options.setAlignment(halign | Qt::AlignTop);
82 options.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
83 QFont f = f10;
84 if (style == Strong)
85 f.setBold(true);
86 else if (style == Emphasis)
87 f.setItalic(true);
88 int wd = hsize * percent / 100;
89 QRect r(cp.rect.x() + cp.rect.width(), 0, wd, vsize);
90 const int ht = static_cast<int>(p.boundingRect(rect: r, text, o: options).height());
91
92 Box b(r, text, f, options);
93 cp.boxes.append(t: b);
94 cp.rect.setSize(QSize(cp.rect.width() + wd, qMax(a: cp.rect.height(), b: ht)));
95}
96
97// use init if initial vsize should be calculated (first breakPage call)
98void PrintOut::breakPage(bool init)
99{
100 static const int LeftAlign = Qt::AlignLeft | Qt::AlignTop;
101 static const int RightAlign = Qt::AlignRight | Qt::AlignTop;
102 QRect r1, r2;
103 int h1 = 0;
104 int h2 = 0;
105
106 if (page > 0)
107 pr->newPage();
108
109 if (!init)
110 page++;
111
112 voffset = 0;
113
114 p.setFont(f10);
115 r1 = QRect(hmargin, voffset, 3 * hsize / 4, vsize);
116 r2 = QRect(r1.x() + r1.width(), voffset, hsize - r1.width(), vsize);
117 h1 = p.boundingRect(rect: r1, flags: LeftAlign, text: pr->docName()).height();
118 if (!init)
119 p.drawText(r: r1, flags: LeftAlign, text: pr->docName());
120 h2 = p.boundingRect(rect: r2, flags: RightAlign, text: QString::number(page)).height();
121 if (!init)
122 p.drawText(r: r2, flags: RightAlign, text: QString::number(page));
123 voffset += qMax(a: h1, b: h2 );
124
125 r1 = QRect(hmargin, voffset, hsize / 2, LeftAlign);
126 p.setFont(f8);
127 h1 = p.boundingRect(rect: r1, flags: LeftAlign, text: dateTime.toString()).height();
128 if (!init)
129 p.drawText(r: r1, flags: LeftAlign, text: dateTime.toString());
130 p.setFont(f10);
131 voffset += qMax(a: h1, b: h2);
132
133 voffset += 4;
134 if (!init)
135 p.drawLine(p1: QPoint(hmargin, voffset), p2: QPoint(hmargin + hsize, voffset));
136 voffset += 14;
137
138 firstParagraph = true;
139
140 if (init) {
141 vsize -= voffset;
142 breakPage(); // now draw it when the vsize is ok
143 }
144
145}
146
147void PrintOut::drawRule(Rule rule)
148{
149 QPen pen;
150
151 switch (rule) {
152 case NoRule:
153 voffset += 5;
154 break;
155 case ThinRule:
156 pen.setColor(QColor(192, 192, 192));
157 pen.setStyle(Qt::DotLine);
158 pen.setWidth(0);
159 p.setPen(pen);
160 voffset += 5;
161 p.drawLine(p1: QPoint(hmargin, voffset),
162 p2: QPoint(hmargin + hsize, voffset));
163 p.setPen(QPen());
164 voffset += 2;
165 break;
166 case ThickRule:
167 voffset += 7;
168 p.drawLine(p1: QPoint(hmargin, voffset),
169 p2: QPoint(hmargin + hsize, voffset));
170 voffset += 4;
171 }
172}
173
174QT_END_NAMESPACE
175

source code of qttools/src/linguist/linguist/printout.cpp