소스 검색

use same QWebPrinter instance in "counting" and "printing" phases

There could be differences in layout during both these phases due
to the underlying WebCore::PrintContext forcing print layout in
the constructor and attempting to restore it back to screen mode
in the destructor. This did not always complete correctly, and in
the last phase it could result in less pages (blank page at end)
or more pages (crash when headers/footers were defined).

This should also speed up processing, as re-layout across phases
is now avoided.
Ashish Kulkarni 7 년 전
부모
커밋
6f77c4640a
2개의 변경된 파일18개의 추가작업 그리고 18개의 파일을 삭제
  1. 12 16
      src/lib/pdfconverter.cc
  2. 6 2
      src/lib/pdfconverter_p.hh

+ 12 - 16
src/lib/pdfconverter.cc

@@ -79,7 +79,7 @@ PdfConverterPrivate::PdfConverterPrivate(PdfGlobal & s, PdfConverter & o) :
 	settings(s), pageLoader(s.load, settings.dpi, true),
 	settings(s), pageLoader(s.load, settings.dpi, true),
 	out(o), printer(0), painter(0)
 	out(o), printer(0), painter(0)
 #ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
 #ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
-	, webPrinter(0), measuringHFLoader(s.load, settings.dpi), hfLoader(s.load, settings.dpi), tocLoader1(s.load, settings.dpi), tocLoader2(s.load, settings.dpi)
+	, measuringHFLoader(s.load, settings.dpi), hfLoader(s.load, settings.dpi), tocLoader1(s.load, settings.dpi), tocLoader2(s.load, settings.dpi)
 	, tocLoader(&tocLoader1), tocLoaderOld(&tocLoader2)
 	, tocLoader(&tocLoader1), tocLoaderOld(&tocLoader2)
     , outline(0), currentHeader(0), currentFooter(0)
     , outline(0), currentHeader(0), currentFooter(0)
 #endif
 #endif
@@ -308,12 +308,12 @@ void PdfConverterPrivate::preprocessPage(PageObject & obj) {
 	}
 	}
 
 
 
 
-	QWebPrinter wp(obj.page->mainFrame(), printer, *painter);
-	obj.pageCount = obj.settings.pagesCount? wp.pageCount(): 0;
+	obj.web_printer = new QWebPrinter(obj.page->mainFrame(), printer, *painter);
+	obj.pageCount = obj.settings.pagesCount? obj.web_printer->pageCount(): 0;
 	pageCount += obj.pageCount;
 	pageCount += obj.pageCount;
 
 
 	if (obj.settings.includeInOutline)
 	if (obj.settings.includeInOutline)
-		outline->addWebPage(obj.page->mainFrame()->title(), wp, obj.page->mainFrame(),
+		outline->addWebPage(obj.page->mainFrame()->title(), *obj.web_printer, obj.page->mainFrame(),
 							obj.settings, obj.localLinks, obj.anchors);
 							obj.settings, obj.localLinks, obj.anchors);
 	else
 	else
 		outline->addEmptyWebPage();
 		outline->addEmptyWebPage();
@@ -824,6 +824,7 @@ void PdfConverterPrivate::spoolPage(int page) {
 	if (actualPage != 1)
 	if (actualPage != 1)
 		printer->newPage();
 		printer->newPage();
 
 
+	QWebPrinter *webPrinter = objects[currentObject].web_printer;
 	webPrinter->spoolPage(page+1);
 	webPrinter->spoolPage(page+1);
 	foreach (QWebElement elm, pageFormElements[page+1]) {
 	foreach (QWebElement elm, pageFormElements[page+1]) {
 		QString type = elm.attribute("type");
 		QString type = elm.attribute("type");
@@ -886,7 +887,8 @@ void PdfConverterPrivate::beginPrintObject(PageObject & obj) {
 		endPrintObject(objects[obj.number-1]);
 		endPrintObject(objects[obj.number-1]);
 	currentObject = obj.number;
 	currentObject = obj.number;
 
 
-	if (!obj.loaderObject || obj.loaderObject->skip) return;
+	QWebPrinter *webPrinter = objects[currentObject].web_printer;
+	if (!obj.loaderObject || obj.loaderObject->skip || webPrinter == 0) return;
 
 
 	QPalette pal = obj.loaderObject->page.palette();
 	QPalette pal = obj.loaderObject->page.palette();
 	pal.setBrush(QPalette::Base, Qt::transparent);
 	pal.setBrush(QPalette::Base, Qt::transparent);
@@ -906,11 +908,6 @@ void PdfConverterPrivate::beginPrintObject(PageObject & obj) {
 			elm.setStyleProperty("color","white");
 			elm.setStyleProperty("color","white");
 	}
 	}
 
 
-	//output
-	webPrinter = new QWebPrinter(obj.page->mainFrame(), printer, *painter);
-	QString l1=obj.page->mainFrame()->url().path().split("/").back()+"#";
-	QString l2=obj.page->mainFrame()->url().toString() + "#";
-
 	outline->fillAnchors(obj.number, obj.anchors);
 	outline->fillAnchors(obj.number, obj.anchors);
 
 
 	//Sort anchors and links by page
 	//Sort anchors and links by page
@@ -953,17 +950,16 @@ void PdfConverterPrivate::endPrintObject(PageObject & obj) {
 	Q_UNUSED(obj);
 	Q_UNUSED(obj);
 	// If this page was skipped, we might not have
 	// If this page was skipped, we might not have
 	// anything to spool to printer..
 	// anything to spool to printer..
-	if (webPrinter != 0) spoolTo(webPrinter->pageCount());
+	if (obj.web_printer != 0) spoolTo(obj.web_printer->pageCount());
 
 
 	pageAnchors.clear();
 	pageAnchors.clear();
 	pageLocalLinks.clear();
 	pageLocalLinks.clear();
 	pageExternalLinks.clear();
 	pageExternalLinks.clear();
 	pageFormElements.clear();
 	pageFormElements.clear();
 
 
-	if (webPrinter != 0) {
-		QWebPrinter *tmp = webPrinter;
-		webPrinter = 0;
-		delete tmp;
+	if (obj.web_printer != 0) {
+		delete obj.web_printer;
+		obj.web_printer = 0;
 
 
 		painter->restore();
 		painter->restore();
 	}
 	}
@@ -997,7 +993,7 @@ void PdfConverterPrivate::printDocument() {
 			beginPrintObject(objects[d]);
 			beginPrintObject(objects[d]);
 			// XXX: In some cases nothing gets loaded at all,
 			// XXX: In some cases nothing gets loaded at all,
 			//      so we would get no webPrinter instance.
 			//      so we would get no webPrinter instance.
-			int pageCount = webPrinter != 0 ? webPrinter->pageCount() : 0;
+			int pageCount = objects[d].web_printer != 0 ? objects[d].web_printer->pageCount() : 0;
 			//const settings::PdfObject & ps = objects[d].settings;
 			//const settings::PdfObject & ps = objects[d].settings;
 
 
 			for(int i=0; i < pageCount; ++i) {
 			for(int i=0; i < pageCount; ++i) {

+ 6 - 2
src/lib/pdfconverter_p.hh

@@ -65,6 +65,8 @@ public:
     QWebPage * measuringHeader;
     QWebPage * measuringHeader;
     // keeps preloaded footer to calculate header height
     // keeps preloaded footer to calculate header height
     QWebPage * measuringFooter;
     QWebPage * measuringFooter;
+    // webprinter instance
+    QWebPrinter *web_printer;
 #endif
 #endif
 
 
 	int firstPageNumber;
 	int firstPageNumber;
@@ -78,6 +80,9 @@ public:
 		anchors.clear();
 		anchors.clear();
 		localLinks.clear();
 		localLinks.clear();
 		externalLinks.clear();
 		externalLinks.clear();
+		if (web_printer != 0)
+			delete web_printer;
+		web_printer=0;
 #endif
 #endif
 		headers.clear();
 		headers.clear();
 		footers.clear();
 		footers.clear();
@@ -89,7 +94,7 @@ public:
 	PageObject(const settings::PdfObject & set, const QString * d=NULL):
 	PageObject(const settings::PdfObject & set, const QString * d=NULL):
 		settings(set), loaderObject(0), page(0)
 		settings(set), loaderObject(0), page(0)
 #ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
 #ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
-		, headerReserveHeight(0), footerReserveHeight(0), measuringHeader(0), measuringFooter(0)
+		, headerReserveHeight(0), footerReserveHeight(0), measuringHeader(0), measuringFooter(0), web_printer(0)
 #endif
 #endif
 	{
 	{
 		if (d) data=*d;
 		if (d) data=*d;
@@ -131,7 +136,6 @@ private:
 	int actualPage;
 	int actualPage;
 	int pageNumber;
 	int pageNumber;
 #ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
 #ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
-	QWebPrinter * webPrinter;
 	int objectPage;
 	int objectPage;