Skip to content
This repository was archived by the owner on Jan 2, 2023. It is now read-only.

Commit 881535f

Browse files
committed
Added support for headers and footers, with a modified qt
1 parent 4bcfe79 commit 881535f

4 files changed

Lines changed: 214 additions & 65 deletions

File tree

qt_webkit.patch

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp
2+
index ae71356..574e14d 100644
3+
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp
4+
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp
5+
@@ -955,10 +955,13 @@ void QWebFrame::print(QPrinter *printer) const
6+
return;
7+
}
8+
printContext.spoolPage(ctx, page - 1, pageRect.width());
9+
- if (j < pageCopies - 1)
10+
+ if (j < pageCopies - 1) {
11+
+ emit printingNewPage(printer,fromPage,toPage,page);
12+
printer->newPage();
13+
+ }
14+
}
15+
-
16+
+ emit printingNewPage(printer,fromPage,toPage,page);
17+
+
18+
if (page == toPage)
19+
break;
20+
21+
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h
22+
index 18ae697..1d40a29 100644
23+
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h
24+
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h
25+
@@ -21,6 +21,8 @@
26+
#ifndef QWEBFRAME_H
27+
#define QWEBFRAME_H
28+
29+
+#define WKHTMLTOPDF_QT_WEBFRAME_PATCH
30+
+
31+
#include <QtCore/qobject.h>
32+
#include <QtCore/qurl.h>
33+
#include <QtCore/qvariant.h>
34+
@@ -191,6 +193,7 @@ Q_SIGNALS:
35+
36+
void iconChanged();
37+
38+
+ void printingNewPage(QPrinter *p, int fromPage, int toPage, int Page) const;
39+
private:
40+
friend class QWebPage;
41+
friend class QWebPagePrivate;

wkhtmltopdf.cc

Lines changed: 156 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,27 @@ void WKHtmlToPdf::usage(FILE * fd) {
5151
" Be aware! There is currently a bug in QT, setting this to low\n"
5252
" will make the application CRASH!\n"
5353
#endif
54-
" -T, --top <top> set page top margin (default 10mm)\n"
55-
" -R, --right <right> set page right margin (default 10mm)\n"
56-
" -B, --bottom <bottom> set page bottom margin (default 10mm)\n"
57-
" -L, --left <left> set page left margin (default 10mm)\n"
54+
" -T, --top <top> page top margin (default 10mm)\n"
55+
" -R, --right <right> page right margin (default 10mm)\n"
56+
" -B, --bottom <bottom> page bottom margin (default 10mm)\n"
57+
" -L, --left <left> page left margin (default 10mm)\n"
58+
#ifdef WKHTMLTOPDF_QT_WEBFRAME_PATCH
59+
" --header-font-size <size> header font size (default 11)\n"
60+
" --header-font-name <name> header font name (default Areal)\n"
61+
" --header-left <text> left aligned header text\n"
62+
" --header-center <text center aligned header text\n"
63+
" --header-right <text> right aligned header text\n"
64+
" --header-line <text> display line below the header\n"
65+
" --footer-font-size <size> footer font size (default 11)\n"
66+
" --footer-font-name <name> footer font name (default Areal)\n"
67+
" --footer-left <text> left aligned footer text\n"
68+
" --footer-center <text> center aligned footer text\n"
69+
" --footer-right <text> right aligned footer text\n"
70+
" --footer-line <text> display line above the footer\n"
71+
" -H, --default-header Add a default header, with the name of the page to the left,\n"
72+
" and the page number to the right, this is short for:\n"
73+
" --header-left='[webpage]' --header-right='[page]/[toPage]' --top 2cm --header-line\n"
74+
#endif
5875
" --read-args-from-stdin Uses each line from stdin, as commandline options\n"
5976
" for a convertion. Using multiple lines here, is much\n"
6077
" faster then calling wkhtmltopdf multiple times\n"
@@ -67,6 +84,15 @@ void WKHtmlToPdf::usage(FILE * fd) {
6784
" <userinfo> := <username> (\":\" <password>)? \"@\"\n"
6885
" <proxy> := \"None\" | <type>? <userinfo>? <host> (\":\" <port>)?\n"
6986
"\n"
87+
#ifdef WKHTMLTOPDF_QT_WEBFRAME_PATCH
88+
"Header and footer text:\n"
89+
"In a header or footer text the following variables can be used\n"
90+
" * [page] Replaced by the number of the pages currently beeing printed\n"
91+
" * [fromPage] Replaced by the number of the first page to be printed\n"
92+
" * [toPage] Replaced by the number of the last page to be printed\n"
93+
" * [webpage] Replaced by the url of the page beeing printed\n"
94+
"\n"
95+
#endif
7096
"Mail bug reports and suggestions to <antialze@gmail.com>.\n"
7197
);
7298
}
@@ -249,56 +275,74 @@ int WKHtmlToPdf::parseLongArg(const char * arg, int morec, const char ** morev)
249275
} else if(!strcmp(arg,"quiet")) {
250276
//Suppres output
251277
quiet = true;
252-
} else if(!strcmp(arg,"input")) {
253-
//Specify the input url
254-
if(morec < 1) {usage(stderr);exit(1);}
255-
in = morev[++used];
256-
} else if(!strcmp(arg,"output")) {
257-
//Specify the name of the output file
258-
if(morec < 1) return -1;
259-
out = morev[++used];
260-
} else if(!strcmp(arg,"proxy")) {
261-
//Set up proxy
262-
if(morec < 1) return -1;
263-
setProxy(morev[++used]);
264-
} else if(!strcmp(arg,"orientation")) {
265-
//Change page orientation
266-
if(morec < 1) return -1;
267-
setOrientation(morev[++used]);
268-
} else if(!strcmp(arg,"pagesize")) {
269-
//Setup paper size
270-
if(morec < 1) return -1;
271-
setPageSize(morev[++used]);
272-
} else if(!strcmp(arg,"grayscale")) {
273-
//Change into grayscale mode
274-
colorMode = QPrinter::GrayScale;
275-
} else if(!strcmp(arg,"lowquality")) {
278+
} else if(!strcmp(arg,"lowquality")) {
276279
//Lower the resolution of the output file (saves some space)
277280
resolution = QPrinter::ScreenResolution;
278281
} else if(!strcmp(arg,"nobackground")) {
279282
//Do not print the background
280283
background = false;
281-
} else if(!strcmp(arg,"dpi")) {
282-
//Change the dpi (the output resolution)
283-
if(morec < 1) return -1;
284-
dpi=atoi(morev[++used]);
285-
} else if(!strcmp(arg,"top")) {
286-
//Set the top margin
287-
if(morec < 1) return -1;
288-
top=parseUnitReal(morev[++used]);
289-
} else if(!strcmp(arg,"right")) {
290-
//Set the right margin
291-
if(morec < 1) return -1;
292-
right=parseUnitReal(morev[++used]);
293-
} else if(!strcmp(arg,"bottom")) {
294-
//Set the bottom margin
295-
if(morec < 1) return -1;
296-
bottom=parseUnitReal(morev[++used]);
297-
} else if(!strcmp(arg,"left")) {
298-
//Set the left margin
299-
if(morec < 1) return -1;
300-
left=parseUnitReal(morev[++used]);
301-
} else return -1; //An invalid option was specified
284+
} else {
285+
if(morec < 1) {usage(stderr);exit(1);}
286+
if(!strcmp(arg,"input"))
287+
//Specify the input url
288+
in = morev[++used];
289+
else if(!strcmp(arg,"output"))
290+
//Specify the name of the output file
291+
out = morev[++used];
292+
else if(!strcmp(arg,"proxy"))
293+
//Set up proxy
294+
setProxy(morev[++used]);
295+
else if(!strcmp(arg,"orientation"))
296+
//Change page orientation
297+
setOrientation(morev[++used]);
298+
else if(!strcmp(arg,"pagesize"))
299+
//Setup paper size
300+
setPageSize(morev[++used]);
301+
else if(!strcmp(arg,"grayscale"))
302+
//Change into grayscale mode
303+
colorMode = QPrinter::GrayScale;
304+
else if(!strcmp(arg,"dpi"))
305+
//Change the dpi (the output resolution)
306+
dpi=atoi(morev[++used]);
307+
else if(!strcmp(arg,"top"))
308+
//Set the top margin
309+
margin_top=parseUnitReal(morev[++used]);
310+
else if(!strcmp(arg,"right"))
311+
//Set the right margin
312+
margin_right=parseUnitReal(morev[++used]);
313+
else if(!strcmp(arg,"bottom"))
314+
//Set the bottom margin
315+
margin_bottom=parseUnitReal(morev[++used]);
316+
else if(!strcmp(arg,"left"))
317+
//Set the left margin
318+
margin_left=parseUnitReal(morev[++used]);
319+
else if(!strcmp(arg,"default-header")) {
320+
header_left="[webpage]";
321+
header_right="[page]/[toPage]";
322+
header_line=true;
323+
margin_top=parseUnitReal("2cm");
324+
} else if(!strcmp(arg,"header-font-name"))
325+
header_font_name=morev[++used];
326+
else if(!strcmp(arg,"header-font-size"))
327+
header_font_size=atoi(morev[++used]);
328+
else if(!strcmp(arg,"header-left"))
329+
header_left=morev[++used];
330+
else if(!strcmp(arg,"header-center"))
331+
header_center=morev[++used];
332+
else if(!strcmp(arg,"header-right"))
333+
header_right=morev[++used];
334+
else if(!strcmp(arg,"footer-font-name"))
335+
footer_font_name=morev[++used];
336+
else if(!strcmp(arg,"footer-font-size"))
337+
footer_font_size=atoi(morev[++used]);
338+
else if(!strcmp(arg,"footer-left"))
339+
footer_left=morev[++used];
340+
else if(!strcmp(arg,"footer-center"))
341+
footer_center=morev[++used];
342+
else if(!strcmp(arg,"footer-right"))
343+
footer_right=morev[++used];
344+
else return -1; //An invalid option was specified
345+
}
302346
return used;
303347
}
304348

@@ -322,9 +366,16 @@ void WKHtmlToPdf::parseArgs(int argc, const char ** argv) {
322366
resolution = QPrinter::HighResolution; //We default to producing good looking large files
323367
background = true; //Draw the background
324368
dpi = -1; //-1 indicates that we will use the default dpi provided by QT
325-
top = right = bottom = left=
369+
margin_top = margin_right = margin_bottom = margin_left=
326370
std::pair<qreal,QPrinter::Unit>(10,QPrinter::Millimeter);
327-
371+
372+
//Setup default header and footer settings
373+
header_font_size = footer_font_size = 11;
374+
header_font_name = footer_font_name = "Arial";
375+
header_line = footer_line = false;
376+
header_left = header_center = header_right = "";
377+
footer_left = footer_right = footer_center = "";
378+
328379
char * val;
329380
//Load configuration from enviornment
330381
if((val = getenv("proxy"))) setProxy(val);
@@ -338,7 +389,7 @@ void WKHtmlToPdf::parseArgs(int argc, const char ** argv) {
338389
s2l['g'] = "grayscale"; s2l['l'] = "lowquality"; s2l['O']="orientation";
339390
s2l['d'] = "dpi"; s2l['T'] = "top"; s2l['B']="bottom";
340391
s2l['R'] = "right"; s2l['L'] = "left"; s2l['b']="nobackground";
341-
392+
s2l['H'] = "default-header";
342393

343394
int x=0; //The number of default arguments read so fare
344395
for(int i=1; i < argc; ++i) {
@@ -408,16 +459,60 @@ QUrl WKHtmlToPdf::guessUrlFromString(const QString &string)
408459
return QUrl(string, QUrl::TolerantMode);
409460
}
410461

411-
462+
/*!
463+
* Connect page signals, to our methods. And do other page
464+
* configurations.
465+
*/
412466
void WKHtmlToPdf::init() {
413-
page.setNetworkAccessManager(&am);
467+
//Allow for network control fine touning.
468+
page.setNetworkAccessManager(&am);
414469
connect(&am, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)),this,
415470
SLOT(sslErrors(QNetworkReply*, const QList<QSslError>&)));
416471
//When loading is progressing we want loadProgress to be called
417472
connect(&page, SIGNAL(loadProgress(int)), this, SLOT(loadProgress(int)));
418473
//Once the loading is done we want loadFinished to be called
419474
connect(&page, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
420-
//Tell the vebview to load for the newly created url
475+
#ifdef WKHTMLTOPDF_QT_WEBFRAME_PATCH
476+
connect(page.mainFrame(), SIGNAL(printingNewPage(QPrinter*,int,int,int)), this, SLOT(newPage(QPrinter*,int,int,int)));
477+
#endif
478+
}
479+
480+
QString WKHtmlToPdf::hfreplace(const QString & q, int f, int t, int p) {
481+
QString _=q;
482+
return _
483+
.replace("[page]",QString::number(p),Qt::CaseInsensitive)
484+
.replace("[toPage]",QString::number(t),Qt::CaseInsensitive)
485+
.replace("[fromPage]",QString::number(f),Qt::CaseInsensitive)
486+
.replace("[webpage]",in);
487+
}
488+
489+
void WKHtmlToPdf::newPage(QPrinter * printer, int f, int t, int p) {
490+
if(!quiet) fprintf(stderr,"Printing page: %d%% \r",(p-f)*100/(t-f));
491+
fflush(stdout);
492+
QPainter & painter = *printer->paintEngine()->painter();
493+
painter.save();
494+
painter.resetMatrix();
495+
int h=printer->pageRect().height();
496+
int w=printer->pageRect().width();
497+
498+
painter.setFont(QFont(header_font_name, header_font_size));
499+
if(header_line) painter.drawLine(0,0,w,0);
500+
int dy = painter.boundingRect(0,0,w,h,Qt::AlignTop,"M").height();
501+
QRect r=QRect(0,0-dy,w,h);
502+
QString x = hfreplace(header_right,f,t,p);
503+
504+
painter.drawText(r, Qt::AlignTop | Qt::AlignLeft, hfreplace(header_left,f,t,p));
505+
painter.drawText(r, Qt::AlignTop | Qt::AlignCenter, hfreplace(header_center,f,t,p));
506+
painter.drawText(r, Qt::AlignTop | Qt::AlignRight, hfreplace(header_right,f,t,p));
507+
508+
painter.setFont(QFont(footer_font_name, footer_font_size));
509+
if(footer_line) painter.drawLine(0,h,w,h);
510+
dy = painter.boundingRect(0,0,w,h,Qt::AlignTop,"M").height();
511+
r=QRect(0,0,w,h+dy);
512+
painter.drawText(r, Qt::AlignBottom | Qt::AlignLeft, hfreplace(footer_left,f,t,p));
513+
painter.drawText(r, Qt::AlignBottom | Qt::AlignCenter, hfreplace(footer_center,f,t,p));
514+
painter.drawText(r, Qt::AlignBottom | Qt::AlignRight, hfreplace(footer_right,f,t,p));
515+
painter.restore();
421516
}
422517

423518
void WKHtmlToPdf::run(int argc, const char ** argv) {
@@ -464,14 +559,16 @@ void WKHtmlToPdf::loadFinished(bool ok) {
464559
QPrinter::PostScriptFormat : QPrinter::PdfFormat
465560
);
466561
p.setOutputFileName(out);
467-
if(left.second != right.second ||
468-
left.second != top.second ||
469-
left.second != bottom.second) {
562+
if(margin_left.second != margin_right.second ||
563+
margin_left.second != margin_top.second ||
564+
margin_left.second != margin_bottom.second) {
470565
fprintf(stderr, "Currently all margin units must be the same!\n");
471566
exit(1);
472567
}
473568

474-
p.setPageMargins(left.first, top.first, right.first, bottom.first, left.second);
569+
p.setPageMargins(margin_left.first, margin_top.first,
570+
margin_right.first, margin_bottom.first,
571+
margin_left.second);
475572

476573
p.setPageSize(pageSize);
477574
p.setOrientation(orientation);

wkhtmltopdf.hh

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,21 @@ public:
4444
QPrinter::Orientation orientation; //What orientation
4545
QPrinter::ColorMode colorMode; //Color or grayscale
4646
QPrinter::PrinterMode resolution; //resolution
47-
int dpi;
48-
std::pair<qreal, QPrinter::Unit> top;
49-
std::pair<qreal, QPrinter::Unit> right;
50-
std::pair<qreal, QPrinter::Unit> bottom;
51-
std::pair<qreal, QPrinter::Unit> left;
47+
int dpi; //The printing dpi
48+
//Specify page margins
49+
std::pair<qreal, QPrinter::Unit> margin_top;
50+
std::pair<qreal, QPrinter::Unit> margin_right;
51+
std::pair<qreal, QPrinter::Unit> margin_bottom;
52+
std::pair<qreal, QPrinter::Unit> margin_left;
5253

54+
//Header / footer settings
55+
int header_font_size, footer_font_size;
56+
QString header_font_name, footer_font_name;
57+
QString header_left, header_center, header_right;
58+
bool header_line, footer_line;
59+
QString footer_left, footer_center, footer_right;
60+
61+
QString hfreplace(const QString & q, int f, int t, int p);
5362
std::pair<qreal, QPrinter::Unit> parseUnitReal(const char * o);
5463
static QUrl guessUrlFromString(const QString &string);
5564
void version(FILE * fd); //Print version information to fd
@@ -63,6 +72,7 @@ public:
6372
void run(int argc, const char** argv);
6473

6574
public slots:
75+
void newPage(QPrinter * p, int fromPage, int toPage, int page);
6676
void loadFinished(bool ok);
6777
void loadProgress(int progress);
6878
void sslErrors(QNetworkReply *reply, const QList<QSslError> &error);

wkhtmltopdf.pro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ TARGET =
99
DEPENDPATH += .
1010
INCLUDEPATH += .
1111

12-
CONFIG -= app_bundle
12+
CONFIG += qt debug
13+
CONFIG -= app_bundle
1314
QT += webkit network
1415

1516
# Input

0 commit comments

Comments
 (0)