Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Improve printing #211

Closed
wants to merge 3 commits into from

2 participants

@milianw

here are three patches, I'd like to upstream.

the first one fixes a build-issue when using build-linux.sh with --headless - it is not really related to the other two, but I was to lazy to create a separate pull request just for that... hope you don't mind

then there is one commit that simplifies the handling of qt-patches in the build-helper.sh, namely the patch files are now read from folders. that way, a user can just dump custom patches there and run the deploy script without changes.

finally, there are three new qt 4.8 patches, that leverage this new patch-folder structure. the patches are improve PhantomJS printing capabilities substantially. Most notably, tables are now printed much nicer (thead, tfoot are repeated and there are no more page-breaks inside table rows). Furthermore users can add a custom header/footer to pages by adding some javascript to their page(s):

    
milianw added some commits
@milianw milianw fix headless-build on linux
in such cases, DISABLE_HEADLESS was unset and hence
the expansion -a -eq 0 resulted in a bash error:

bash: [: too many arguments

this is fixed now by using string-based comparison
de669e8
@milianw milianw simplify maintenance of custom qt-patches during deployment
generic patches now reside in deploy/qt-patches/all
while 4.8 patches are now in deploy/qt-patches/4.8

all *.patch files in these folders are applied during deployment
d3d9b0c
@milianw milianw improve PhantomJS printing
the webpage needs to define the following java script functions:

<script type="text/javascript">
var PhantomJSPrinting = {
  // supported units: mm, cm, in, px
  headerHeight : function() { return '1cm'; },
  footerHeight : function() { return '1cm'; },
  // just return any kind of html that make up the header/footer
  // it should not be taller than what is returned in header/footerHeight()
  header: function(currentPage, totalPages) { return currentPage + " / " + totalPages; },
  footer: function(currentPage, totalPages) { return currentPage + " / " + totalPages; }
};
</script>

The page-counter can be reset by adding the class "phantomjs_reset_pagination"
attribute to html block-elements that should reset the counter.

page-break-inside:avoid is now properly honored by block elements

thead and tfoot of tables are now repeated on every page the table spans

rows are layouted such that a page-break is avoided inside them
5605fed
@milianw

you can see an example .html & .pdf file here:

https://userpage.physik.fu-berlin.de/~milianw/phantomjs/printing/

@ariya
Owner

For reasons described elsewhere, I rather have the issue linked from the commit log. But if you don't have time to add them, I'll try to amend the commit message as I cherry-pick it.

@milianw

is there a issue for this? I haven't found one.

I'd welcome it if you could just add the "issue: ..." line yourself - sorry for the inconvenience!

@ariya
Owner

Well yeah, technically a feature should be filed in the issue tracker as well (per our Contribution Guide).

@milianw

so, should I create a new issue? I found http://code.google.com/p/phantomjs/issues/detail?id=63 which is I think at least partially fixed by this - I'd of course also be ok with you just merging these patches with the "issue: ..." line added.

many thanks

@ariya
Owner

Sure, 63 seems to be a representative issue which I can use. Thanks!

@ariya
Owner

I'm going to hold off merging the printing patch that requires global object (that's not a good practice). Once we have a better JS binding machinery, this will be better handled.

This is also a good reason to prepare an issue in the tracker which discuss the problem/solution.

@milianw

see http://code.google.com/p/phantomjs/issues/detail?id=410&start=100 - could you please elaborate on which "global object" you mean?

@milianw

partially merged, rest is going to appear in a new mr soon

@milianw milianw closed this
@milianw milianw referenced this pull request
Merged

Improve Table Printing #344

@milianw milianw referenced this pull request
Closed

Changing PDF Margins #10063

@ashkulz ashkulz referenced this pull request from a commit
Ashish Kulkarni apply 0006-properly-honor-page-breack-before-after-avoid-in-blo.patch…
… from PR #211
a6ee1c3
@ariya ariya referenced this pull request from a commit
@milianw milianw Prevent page breaks in table rows.
This was part of a previous PhantomJS release but got reverted
when the Qt source tree was imported. See the old pull request
here: #211

http://code.google.com/p/phantomjs/issues/detail?id=880
5c87852
@ariya ariya referenced this pull request from a commit
@milianw milianw Repeat thead and tfoot when table contains page breaks.
This was already done in #211
but somehow got lost when the Qt source tree was imported.

Note that I even improved this patch a bit to also properly repaint
the borders of cells in thead/tfoot.

http://code.google.com/p/phantomjs/issues/detail?id=615
2d778f6
@ariya ariya referenced this pull request from a commit
@ashkulz ashkulz Implement "page-break-inside: avoid" for non-floating block elements.
This patch is taken from https://bugs.webkit.org/show_bug.cgi?id=5097#c17

It was originally part of PR #211 but was possibly overlooked in PR #344
(when the other two patches got reapplied after the QT source import).
3ed2f68
@milianw milianw referenced this pull request from a commit in KDAB/qtwebkit
@milianw milianw Prevent page breaks in table rows.
This was part of a previous PhantomJS release but got reverted
when the Qt source tree was imported. See the old pull request
here: ariya/phantomjs#211

http://code.google.com/p/phantomjs/issues/detail?id=880

Change-Id: I2f193dfb69b5cd9c86cb444bd74950e17dc14424
1440b49
@milianw milianw referenced this pull request from a commit in KDAB/qtwebkit
@milianw milianw Repeat thead and tfoot when table contains page breaks.
This was already done in ariya/phantomjs#211
but somehow got lost when the Qt source tree was imported.

Note that I even improved this patch a bit to also properly repaint
the borders of cells in thead/tfoot.

http://code.google.com/p/phantomjs/issues/detail?id=615

Change-Id: Iad71002e095fefdad1efc3bc44f10b15a355f0e2
f55cd7a
@milianw milianw referenced this pull request from a commit in KDAB/qtwebkit
@milianw milianw Prevent page breaks in table rows.
This was part of a previous PhantomJS release but got reverted
when the Qt source tree was imported. See the old pull request
here: ariya/phantomjs#211

http://code.google.com/p/phantomjs/issues/detail?id=880

Change-Id: I2f193dfb69b5cd9c86cb444bd74950e17dc14424
3fe9afb
@milianw milianw referenced this pull request from a commit in KDAB/qtwebkit
@milianw milianw Repeat thead and tfoot when table contains page breaks.
This was already done in ariya/phantomjs#211
but somehow got lost when the Qt source tree was imported.

Note that I even improved this patch a bit to also properly repaint
the borders of cells in thead/tfoot.

http://code.google.com/p/phantomjs/issues/detail?id=615

Change-Id: Iad71002e095fefdad1efc3bc44f10b15a355f0e2
406ae2d
@ashkulz ashkulz referenced this pull request from a commit in wkhtmltopdf/qtwebkit
@milianw milianw Prevent page breaks in table rows.
This was part of a previous PhantomJS release but got reverted
when the Qt source tree was imported. See the old pull request
here: ariya/phantomjs#211

http://code.google.com/p/phantomjs/issues/detail?id=880

Change-Id: I2f193dfb69b5cd9c86cb444bd74950e17dc14424
70dead1
@ashkulz ashkulz referenced this pull request from a commit in wkhtmltopdf/qtwebkit
@milianw milianw Repeat thead and tfoot when table contains page breaks.
This was already done in ariya/phantomjs#211
but somehow got lost when the Qt source tree was imported.

Note that I even improved this patch a bit to also properly repaint
the borders of cells in thead/tfoot.

http://code.google.com/p/phantomjs/issues/detail?id=615

Change-Id: Iad71002e095fefdad1efc3bc44f10b15a355f0e2
249acce
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 28, 2012
  1. @milianw

    fix headless-build on linux

    milianw authored
    in such cases, DISABLE_HEADLESS was unset and hence
    the expansion -a -eq 0 resulted in a bash error:
    
    bash: [: too many arguments
    
    this is fixed now by using string-based comparison
  2. @milianw

    simplify maintenance of custom qt-patches during deployment

    milianw authored
    generic patches now reside in deploy/qt-patches/all
    while 4.8 patches are now in deploy/qt-patches/4.8
    
    all *.patch files in these folders are applied during deployment
  3. @milianw

    improve PhantomJS printing

    milianw authored
    the webpage needs to define the following java script functions:
    
    <script type="text/javascript">
    var PhantomJSPrinting = {
      // supported units: mm, cm, in, px
      headerHeight : function() { return '1cm'; },
      footerHeight : function() { return '1cm'; },
      // just return any kind of html that make up the header/footer
      // it should not be taller than what is returned in header/footerHeight()
      header: function(currentPage, totalPages) { return currentPage + " / " + totalPages; },
      footer: function(currentPage, totalPages) { return currentPage + " / " + totalPages; }
    };
    </script>
    
    The page-counter can be reset by adding the class "phantomjs_reset_pagination"
    attribute to html block-elements that should reset the counter.
    
    page-break-inside:avoid is now properly honored by block elements
    
    thead and tfoot of tables are now repeated on every page the table spans
    
    rows are layouted such that a page-break is avoided inside them
This page is out of date. Refresh to see the latest.
View
19 deploy/build-helper.sh
@@ -135,6 +135,14 @@ extract_qt() {
mv $DEPLOY_DIR/qt-everywhere-opensource-src-$QT_VERSION $QT_FOLDER
}
+apply_patches() {
+ for p in $(ls $@); do
+ echo
+ echo "applying patch: $p"
+ patch -p1 < $p
+ done
+}
+
patch_qt() {
pushd $QT_FOLDER
echo "Patching Qt"
@@ -144,21 +152,16 @@ patch_qt() {
fi
if [ $QT_VERSION = 4.8.0 ] ; then
- patch -p1 < ../qt48_enable_debugger.patch
- patch -p1 < ../qt48_fix_inspector.patch
- patch -p1 < ../qt48_headless_and_pdf_fixes.patch
- patch -p1 < ../qt48_enable_file_input_click.patch
+ apply_patches ../qt-patches/4.8/*.patch
# Build in lighthose mode for an x-less build
- if [ $QT_HEADLESS -eq 1 -a $DISABLE_HEADLESS -eq 0 ] ; then
+ if [[ "$QT_HEADLESS" == "1" && "$DISABLE_HEADLESS" != "1" ]] ; then
echo "Building 4.8 in qpa headless mode"
QT_CFG+=' -qpa '
fi
fi
- patch configure ../allow-static-qtwebkit.patch
- patch -p1 < ../qapplication_skip_qtmenu.patch
- patch -p1 < ../disable_quicktime_video.patch
+ apply_patches ../qt-patches/all/*.patch
# Tests don't build well with -static, but we don't need to build them
rm -rf src/3rdparty/webkit/Source/WebKit/qt/tests
View
0  deploy/qt48_enable_debugger.patch → deploy/qt-patches/4.8/0001-enable_debugger.patch
File renamed without changes
View
0  deploy/qt48_fix_inspector.patch → deploy/qt-patches/4.8/0002-fix_inspector.patch
File renamed without changes
View
0  deploy/qt48_headless_and_pdf_fixes.patch → .../qt-patches/4.8/0003-headless_and_pdf_fixes.patch
File renamed without changes
View
0  deploy/qt48_enable_file_input_click.patch → ...qt-patches/4.8/0004-enable_file_input_click.patch
File renamed without changes
View
382 deploy/qt-patches/4.8/0005-make-it-possible-to-print-web-pages-with-user-define.patch
@@ -0,0 +1,382 @@
+From 5fc23395ea9d78bf7216e2f34b99e57cc415ab5c Mon Sep 17 00:00:00 2001
+From: Milian Wolff <milian.wolff@kdab.com>
+Date: Tue, 28 Feb 2012 13:28:13 +0100
+Subject: [PATCH 1/3] make it possible to print web pages with user-defined
+ headers and footers
+
+the webpage needs to define the following java script functions:
+
+<script type="text/javascript">
+var PhantomJSPrinting = {
+ // supported units: mm, cm, in, px
+ headerHeight : function() { return '1cm'; },
+ footerHeight : function() { return '1cm'; },
+ // just return any kind of html that make up the header/footer
+ // it should not be taller than what is returned in header/footerHeight()
+ header: function(currentPage, totalPages) { return currentPage + " / " + totalPages; },
+ footer: function(currentPage, totalPages) { return currentPage + " / " + totalPages; }
+};
+</script>
+
+The page-counter can be reset by adding the class "phantomjs_reset_pagination"
+attribute to html block-elements that should reset the counter.
+---
+ src/3rdparty/webkit/Source/WebCore/page/Frame.cpp | 34 ++++
+ src/3rdparty/webkit/Source/WebCore/page/Frame.h | 4 +
+ .../webkit/Source/WebCore/page/PrintContext.cpp | 11 +-
+ .../Source/WebCore/rendering/RenderBlock.cpp | 9 +
+ .../webkit/Source/WebKit/qt/Api/qwebframe.cpp | 13 ++-
+ .../webkit/Source/WebKit/qt/Api/qwebframe_p.h | 2 +
+ .../WebKit/qt/Api/qwebframe_printingaddons_p.h | 165 ++++++++++++++++++++
+ 7 files changed, 235 insertions(+), 3 deletions(-)
+ create mode 100644 src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_printingaddons_p.h
+
+diff --git a/src/3rdparty/webkit/Source/WebCore/page/Frame.cpp b/src/3rdparty/webkit/Source/WebCore/page/Frame.cpp
+index 6128231..835be73 100644
+--- a/src/3rdparty/webkit/Source/WebCore/page/Frame.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/page/Frame.cpp
+@@ -544,6 +544,8 @@ Color Frame::getDocumentBackgroundColor() const
+
+ void Frame::setPrinting(bool printing, const FloatSize& pageSize, float maximumShrinkRatio, AdjustViewSizeOrNot shouldAdjustViewSize)
+ {
++ m_pageResets.clear();
++
+ m_doc->setPrinting(printing);
+ view()->adjustMediaTypeForPrinting(printing);
+
+@@ -561,6 +563,38 @@ void Frame::setPrinting(bool printing, const FloatSize& pageSize, float maximumS
+ child->setPrinting(printing, IntSize(), 0, shouldAdjustViewSize);
+ }
+
++void Frame::addResetPage(int page)
++{
++ m_pageResets.append(page);
++}
++
++void Frame::getPagination(int page, int pages, int& logicalPage, int& logicalPages) const
++{
++ logicalPage = page;
++ logicalPages = pages;
++ int last_j = 0;
++ int j = 0;
++ for(size_t i = 0; i < m_pageResets.size(); ++i) {
++ j = m_pageResets.at(i);
++ if (j >= page) {
++ break;
++ }
++ last_j = j;
++ }
++ if (page > last_j) {
++ logicalPage = page - last_j;
++ }
++ if (last_j) {
++ if (j > last_j) {
++ logicalPages = j - last_j;
++ } else {
++ logicalPages = pages - last_j;
++ }
++ } else if (j >= page && j < pages) {
++ logicalPages = j;
++ }
++}
++
+ void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
+ {
+ if (!m_page)
+diff --git a/src/3rdparty/webkit/Source/WebCore/page/Frame.h b/src/3rdparty/webkit/Source/WebCore/page/Frame.h
+index 2d76aee..96ba9e6 100644
+--- a/src/3rdparty/webkit/Source/WebCore/page/Frame.h
++++ b/src/3rdparty/webkit/Source/WebCore/page/Frame.h
+@@ -144,6 +144,8 @@ namespace WebCore {
+
+ enum AdjustViewSizeOrNot { DoNotAdjustViewSize, AdjustViewSize };
+ void setPrinting(bool printing, const FloatSize& pageSize, float maximumShrinkRatio, AdjustViewSizeOrNot);
++ void addResetPage(int page);
++ void getPagination(int page, int pages, int &logicalPage, int &logicalPages) const;
+
+ bool inViewSourceMode() const;
+ void setInViewSourceMode(bool = true);
+@@ -251,6 +253,8 @@ namespace WebCore {
+ bool m_isDisconnected;
+ bool m_excludeFromTextSearch;
+
++ Vector<int> m_pageResets;
++
+ #if ENABLE(TILED_BACKING_STORE)
+ // FIXME: The tiled backing store belongs in FrameView, not Frame.
+
+diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
+index 660ad11..a1b8f84 100644
+--- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
+@@ -82,9 +82,16 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
+ float pageWidth;
+ float pageHeight;
+ if (isHorizontal) {
+- float ratio = printRect.height() / printRect.width();
+ pageWidth = view->docWidth();
+- pageHeight = floorf(pageWidth * ratio);
++ ///NOTE: if we do not reuse the previously set logical page height,
++ /// we can end up with off-by-one erros in the page height,
++ /// leading to rendering issues (e.g. rows overlap pagebreaks)
++ if (view->pageLogicalHeight() == 0) {
++ float ratio = printRect.height() / printRect.width();
++ pageHeight = floorf(pageWidth * ratio);
++ } else {
++ pageHeight = view->pageLogicalHeight();
++ }
+ } else {
+ float ratio = printRect.width() / printRect.height();
+ pageHeight = view->docHeight();
+diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp
+index 4ad1bfe..01810ee 100644
+--- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp
+@@ -1348,6 +1348,15 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
+ }
+ }
+ setNeedsLayout(false);
++
++ if (document()->printing()) {
++ // PHANTOMJS CUSTOM: reset pagination counter for printing
++ StyledElement* elem = dynamic_cast<StyledElement*>(generatingNode());
++ if (elem && elem->hasClass() && elem->classNames().contains("phantomjs_reset_pagination")) {
++ frame()->addResetPage(y() / view()->layoutState()->m_pageLogicalHeight);
++ }
++ }
++
+ }
+
+ void RenderBlock::addOverflowFromChildren()
+diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
+index 5ea7059..4094e6d 100644
+--- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
+@@ -110,6 +110,8 @@
+ #include <qregion.h>
+ #include <qnetworkrequest.h>
+
++#include "qwebframe_printingaddons_p.h"
++
+ using namespace WebCore;
+
+ // from text/qfont.cpp
+@@ -1437,6 +1439,8 @@ void QWebFrame::print(QPrinter *printer) const
+ if (!painter.begin(printer))
+ return;
+
++ HeaderFooter headerFooter(this, printer);
++
+ const qreal zoomFactorX = (qreal)printer->logicalDpiX() / qt_defaultDpi();
+ const qreal zoomFactorY = (qreal)printer->logicalDpiY() / qt_defaultDpi();
+
+@@ -1449,7 +1453,7 @@ void QWebFrame::print(QPrinter *printer) const
+ int(qprinterRect.width() / zoomFactorX),
+ int(qprinterRect.height() / zoomFactorY));
+
+- printContext.begin(pageRect.width());
++ printContext.begin(pageRect.width(), pageRect.height());
+
+ printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight);
+
+@@ -1499,6 +1503,13 @@ void QWebFrame::print(QPrinter *printer) const
+ printContext.end();
+ return;
+ }
++ if (headerFooter.isValid()) {
++ // print header/footer
++ int logicalPage, logicalPages;
++ d->frame->getPagination(page, printContext.pageCount(), logicalPage, logicalPages);
++ headerFooter.paintHeader(ctx, pageRect, logicalPage, logicalPages);
++ headerFooter.paintFooter(ctx, pageRect, logicalPage, logicalPages);
++ }
+ printContext.spoolPage(ctx, page - 1, pageRect.width());
+ if (j < pageCopies - 1)
+ printer->newPage();
+diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
+index 4108972..903db85 100644
+--- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
+@@ -108,6 +108,8 @@ public:
+ void emitUrlChanged();
+ void _q_orientationChanged();
+
++ static WebCore::Frame* webcoreFrame(QWebFrame* frame) { return frame->d->frame; };
++
+ QWebFrame *q;
+ Qt::ScrollBarPolicy horizontalScrollBarPolicy;
+ Qt::ScrollBarPolicy verticalScrollBarPolicy;
+diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_printingaddons_p.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_printingaddons_p.h
+new file mode 100644
+index 0000000..e79b307
+--- /dev/null
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_printingaddons_p.h
+@@ -0,0 +1,165 @@
++/*
++ Copyright (C) 2012 Milian Wolff, KDAB (milian.wolff@kdab.com)
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Library General Public
++ License as published by the Free Software Foundation; either
++ version 2 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Library General Public License for more details.
++
++ You should have received a copy of the GNU Library General Public License
++ along with this library; see the file COPYING.LIB. If not, write to
++ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ Boston, MA 02110-1301, USA.
++*/
++
++#ifndef QWEBFRAME_PRINTINGADDONS_P_H
++#define QWEBFRAME_PRINTINGADDONS_P_H
++
++#include "qwebframe.h"
++#include "qwebframe_p.h"
++
++#include <qprinter.h>
++#include <qstring.h>
++
++#include "GraphicsContext.h"
++#include "PrintContext.h"
++
++#include <iostream>
++
++// for custom header or footers in printing
++class HeaderFooter
++{
++public:
++ HeaderFooter(const QWebFrame* frame, QPrinter* printer);
++ ~HeaderFooter();
++
++ void setPageRect(const WebCore::IntRect& rect);
++
++ void paintHeader(WebCore::GraphicsContext& ctx, const WebCore::IntRect& pageRect, int pageNum, int totalPages);
++ void paintFooter(WebCore::GraphicsContext& ctx, const WebCore::IntRect& pageRect, int pageNum, int totalPages);
++
++ bool isValid()
++ {
++ return headerHeight > 0 || footerHeight > 0;
++ }
++
++private:
++ QWebFrame* masterFrame;
++ QWebPage page;
++ qreal headerHeight;
++ qreal footerHeight;
++
++ WebCore::PrintContext* printCtx;
++
++ qreal stringToPointSize(const QString &string)
++ {
++ static const struct {
++ QString unit;
++ qreal factor;
++ } units[] = {
++ { QLatin1String("mm"), 72 / 25.4 },
++ { QLatin1String("cm"), 72 / 2.54 },
++ { QLatin1String("in"), 72 },
++ { QLatin1String("px"), 72.0 / 72.0 / 2.54 },
++ { QLatin1String(""), 72.0 / 72.0 / 2.54 }
++ };
++ for (uint i = 0; i < sizeof(units) / sizeof(units[0]); ++i) {
++ if (string.endsWith(units[i].unit)) {
++ QString value = string;
++ value.chop(units[i].unit.length());
++ return value.toDouble() * units[i].factor;
++ }
++ }
++ return 0;
++ }
++ void paint(WebCore::GraphicsContext& ctx, const WebCore::IntRect& pageRect, const QString& contents, int height);
++};
++
++HeaderFooter::HeaderFooter(const QWebFrame* frame, QPrinter* printer)
++: masterFrame(const_cast<QWebFrame*>(frame))
++, printCtx(0)
++{
++ headerHeight = qMax(qreal(0), stringToPointSize(masterFrame->evaluateJavaScript(QLatin1String("PhantomJSPrinting.headerHeight()")).toString()));
++ footerHeight = qMax(qreal(0), stringToPointSize(masterFrame->evaluateJavaScript(QLatin1String("PhantomJSPrinting.footerHeight()")).toString()));
++
++ if (isValid()) {
++ // figure out the header/footer height in *DevicePixel*
++ // based on the height given in *Points*
++ qreal marginLeft, marginRight, marginTop, marginBottom;
++ // find existing margins
++ printer->getPageMargins(&marginLeft, &marginTop, &marginRight, &marginBottom, QPrinter::DevicePixel);
++ const qreal oldMarginTop = marginTop;
++ const qreal oldMarginBottom = marginTop;
++
++ printer->getPageMargins(&marginLeft, &marginTop, &marginRight, &marginBottom, QPrinter::Point);
++ // increase margins to hold header+footer
++ marginTop += headerHeight;
++ marginBottom += footerHeight;
++ printer->setPageMargins(marginLeft, marginTop, marginRight, marginBottom, QPrinter::Point);
++
++ // calculate actual heights
++ printer->getPageMargins(&marginLeft, &marginTop, &marginRight, &marginBottom, QPrinter::DevicePixel);
++ headerHeight = marginTop - oldMarginTop;
++ footerHeight = marginBottom - oldMarginBottom;
++
++ printCtx = new WebCore::PrintContext(QWebFramePrivate::webcoreFrame(page.mainFrame()));
++ }
++}
++
++HeaderFooter::~HeaderFooter()
++{
++ delete printCtx;
++ printCtx = 0;
++}
++
++void HeaderFooter::paintHeader(WebCore::GraphicsContext& ctx, const WebCore::IntRect& pageRect, int pageNum, int totalPages)
++{
++ if (!headerHeight) {
++ return;
++ }
++ const QString c = masterFrame->evaluateJavaScript(QString::fromLatin1("PhantomJSPrinting.header(%1, %2)").arg(pageNum).arg(totalPages)).toString();
++ if (c.isEmpty()) {
++ return;
++ }
++
++ ctx.translate(0, -headerHeight);
++ paint(ctx, pageRect, c, headerHeight);
++ ctx.translate(0, +headerHeight);
++}
++
++void HeaderFooter::paintFooter(WebCore::GraphicsContext& ctx, const WebCore::IntRect& pageRect, int pageNum, int totalPages)
++{
++ if (!footerHeight) {
++ return;
++ }
++ const QString c = masterFrame->evaluateJavaScript(QString::fromLatin1("PhantomJSPrinting.footer(%1, %2)").arg(pageNum).arg(totalPages)).toString();
++ if (c.isEmpty()) {
++ return;
++ }
++
++ const int offset = pageRect.height();
++ ctx.translate(0, +offset);
++ paint(ctx, pageRect, c, footerHeight);
++ ctx.translate(0, -offset);
++}
++
++void HeaderFooter::paint(WebCore::GraphicsContext& ctx, const WebCore::IntRect& pageRect, const QString& contents, int height)
++{
++ page.mainFrame()->setHtml(contents);
++
++ printCtx->begin(pageRect.width(), height);
++ float tempHeight;
++ printCtx->computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, tempHeight);
++
++ printCtx->spoolPage(ctx, 0, pageRect.width());
++
++ printCtx->end();
++}
++
++
++#endif // QWEBFRAME_PRINTINGADDONS_P_H
+--
+1.7.5.4
+
View
27 deploy/qt-patches/4.8/0006-properly-honor-page-breack-before-after-avoid-in-blo.patch
@@ -0,0 +1,27 @@
+From 39ddf9edd4c0ece8628072ab659e99cd9155798e Mon Sep 17 00:00:00 2001
+From: Milian Wolff <milian.wolff@kdab.com>
+Date: Tue, 28 Feb 2012 13:33:01 +0100
+Subject: [PATCH 2/3] properly honor page-breack-{before,after}:avoid in block
+ elements
+
+see also: https://bugs.webkit.org/show_bug.cgi?id=5097#c17
+---
+ .../Source/WebCore/rendering/RenderBlock.cpp | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp
+index 01810ee..3fb6d2d 100644
+--- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp
+@@ -6054,7 +6054,7 @@ int RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo
+
+ int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
+ {
+- bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
++ bool isUnsplittable = child->isReplaced() || child->scrollsOverflow() || child->style()->pageBreakInside() == PBAVOID;
+ if (!isUnsplittable)
+ return logicalOffset;
+ int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
+--
+1.7.5.4
+
View
201 deploy/qt-patches/4.8/0007-improve-printing-of-tables.patch
@@ -0,0 +1,201 @@
+From 25ecd9c89a7e4763f9d4848101a77f688478db77 Mon Sep 17 00:00:00 2001
+From: Milian Wolff <milian.wolff@kdab.com>
+Date: Tue, 28 Feb 2012 13:34:22 +0100
+Subject: [PATCH 3/3] improve printing of tables
+
+- header/footer rows are repeated on every page the table spans
+- rows are layouted such that a page-break is avoided inside them
+---
+ .../WebCore/rendering/RenderBlockLineLayout.cpp | 3 +-
+ .../Source/WebCore/rendering/RenderTable.cpp | 60 +++++++++++++++++++-
+ .../WebCore/rendering/RenderTableSection.cpp | 38 +++++++++++-
+ .../Source/WebCore/rendering/RenderTableSection.h | 2 +-
+ 4 files changed, 95 insertions(+), 8 deletions(-)
+
+diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+index 2e92801..1690c2f 100644
+--- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+@@ -956,7 +956,8 @@ void RenderBlock::layoutRunsAndFloats(bool fullLayout, bool hasInlineChild, Vect
+ repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow());
+ }
+
+- if (paginated) {
++ // table cell pagination is handled in RenderTableSection
++ if (paginated && !isTableCell()) {
+ int adjustment = 0;
+ adjustLinePositionForPagination(lineBox, adjustment);
+ if (adjustment) {
+diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
+index 73b0801..790c1ce 100644
+--- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
+@@ -302,11 +302,20 @@ void RenderTable::layout()
+
+ bool collapsing = collapseBorders();
+
++ // repeat header and footer on each page
++ int headHeight = 0;
++ int footHeight = 0;
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->isTableSection()) {
+ child->layoutIfNeeded();
+ RenderTableSection* section = toRenderTableSection(child);
+- totalSectionLogicalHeight += section->calcRowLogicalHeight();
++ int rowHeight = section->calcRowLogicalHeight();
++ if (child == m_head) {
++ headHeight = rowHeight;
++ } else if (child == m_foot) {
++ footHeight = rowHeight;
++ }
++ totalSectionLogicalHeight += rowHeight;
+ if (collapsing)
+ section->recalcOuterBorder();
+ ASSERT(!section->needsLayout());
+@@ -355,7 +364,7 @@ void RenderTable::layout()
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->isTableSection())
+ // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one.
+- toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0);
++ toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0, headHeight, footHeight);
+ }
+
+ if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
+@@ -503,7 +512,52 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
+ child->paint(info, childPoint.x(), childPoint.y());
+ }
+ }
+-
++
++ if (view()->pageLogicalHeight()) {
++ // re-paint header/footer if table is split over multiple pages
++ if (m_head) {
++ IntPoint childPoint = flipForWritingMode(m_head, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
++ if (!info.rect.contains(childPoint.x() + m_head->x(), childPoint.y() + m_head->y())) {
++ dynamic_cast<RenderObject*>(m_head)->paint(info, childPoint.x(), info.rect.y() - m_head->y());
++ }
++ }
++ if (m_foot) {
++ IntPoint childPoint = flipForWritingMode(m_foot, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
++ if (!info.rect.contains(childPoint.x() + m_foot->x(), childPoint.y() + m_foot->y())) {
++ // find actual end of table on current page
++ int dy = 0;
++ const int max_dy = info.rect.y() + info.rect.height();
++ const int vspace = vBorderSpacing();
++ for (RenderObject* section = firstChild(); section; section = section->nextSibling()) {
++ if (section->isTableSection()) {
++ if (toRenderBox(section)->y() > max_dy) {
++ continue;
++ }
++ int i = 0;
++ for(RenderObject* row = section->firstChild(); row; row = row->nextSibling()) {
++ if (!row->isTableRow()) {
++ continue;
++ }
++ // get actual bottom-y position of this row - pretty complicated, how could this be simplified?
++ // note how we have to take the rowPoint and section's y-offset into account, see e.g.
++ // RenderTableSection::paint where this is also done...
++ IntPoint rowPoint = flipForWritingMode(toRenderBox(row), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
++ int row_dy = rowPoint.y() + toRenderBox(row)->y() + toRenderBox(row)->logicalHeight() + toRenderBox(section)->y();
++ if (row_dy < max_dy && row_dy > dy) {
++ dy = row_dy;
++ } else if (row_dy > max_dy) {
++ break;
++ }
++ i++;
++ }
++ }
++ }
++ dynamic_cast<RenderObject*>(m_foot)->paint(info, childPoint.x(),
++ dy - m_foot->y());
++ }
++ }
++ }
++
+ if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) {
+ // Collect all the unique border styles that we want to paint in a sorted list. Once we
+ // have all the styles sorted, we then do individual passes, painting each style of border
+diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
+index 7d414a0..1e90ac6 100644
+--- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
+@@ -414,7 +414,7 @@ void RenderTableSection::layout()
+ setNeedsLayout(false);
+ }
+
+-int RenderTableSection::layoutRows(int toAdd)
++int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
+ {
+ #ifndef NDEBUG
+ setNeedsLayoutIsForbidden(true);
+@@ -496,12 +496,40 @@ int RenderTableSection::layoutRows(int toAdd)
+
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
+
++ WTF::Vector<int> logicalHeightsForPrinting;
++ // make sure that rows do not overlap a page break
++ if (view()->layoutState()->pageLogicalHeight()) {
++ logicalHeightsForPrinting.resize(totalRows);
++ int pageOffset = 0;
++ for(int r = 0; r < totalRows; ++r) {
++ const int childLogicalHeight = m_rowPos[r + 1] - m_rowPos[r] - (m_grid[r].rowRenderer ? vspacing : 0);
++ logicalHeightsForPrinting[r] = childLogicalHeight;
++ LayoutState* layoutState = view()->layoutState();
++ const int pageLogicalHeight = layoutState->m_pageLogicalHeight;
++ if (childLogicalHeight < pageLogicalHeight - footHeight) {
++ const IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
++ const int logicalOffset = m_rowPos[r] + pageOffset;
++ const int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
++ const int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
++ if (remainingLogicalHeight - footHeight < childLogicalHeight) {
++ pageOffset += remainingLogicalHeight + headHeight;
++ }
++ }
++ m_rowPos[r] += pageOffset;
++ }
++ m_rowPos[totalRows] += pageOffset;
++ }
++
+ for (int r = 0; r < totalRows; r++) {
+ // Set the row's x/y position and width/height.
+ if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) {
+ rowRenderer->setLocation(0, m_rowPos[r]);
+ rowRenderer->setLogicalWidth(logicalWidth());
+- rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing);
++ if (view()->layoutState()->pageLogicalHeight()) {
++ rowRenderer->setLogicalHeight(logicalHeightsForPrinting[r]);
++ } else {
++ rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing);
++ }
+ rowRenderer->updateLayerTransform();
+ }
+
+@@ -513,7 +541,11 @@ int RenderTableSection::layoutRows(int toAdd)
+ continue;
+
+ rindx = cell->row();
+- rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
++ if (view()->layoutState()->pageLogicalHeight() && cell->rowSpan() == 1) {
++ rHeight = logicalHeightsForPrinting[rindx];
++ } else {
++ rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
++ }
+
+ // Force percent height children to lay themselves out again.
+ // This will cause these children to grow to fill the cell.
+diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
+index db6edc2..9d912a0 100644
+--- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
++++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
+@@ -49,7 +49,7 @@ public:
+
+ void setCellLogicalWidths();
+ int calcRowLogicalHeight();
+- int layoutRows(int logicalHeight);
++ int layoutRows(int logicalHeight, int headHeight, int footHeight);
+
+ RenderTable* table() const { return toRenderTable(parent()); }
+
+--
+1.7.5.4
+
View
4 deploy/allow-static-qtwebkit.patch → ...y/qt-patches/all/0001-allow-static-qtwebkit.patch
@@ -1,5 +1,5 @@
---- configure 2011-03-29 22:16:21.000000000 -0700
-+++ configure.new 2011-08-21 22:11:16.000000000 -0700
+--- a/configure 2011-03-29 22:16:21.000000000 -0700
++++ b/configure 2011-08-21 22:11:16.000000000 -0700
@@ -7160,13 +7160,6 @@ if [ "$CFG_GUI" = "no" ]; then
canBuildWebKit="no"
fi
View
0  deploy/qapplication_skip_qtmenu.patch → ...t-patches/all/0002-qapplication-skip-qtmenu.patch
File renamed without changes
View
0  deploy/disable_quicktime_video.patch → ...qt-patches/all/0003-disable-quicktime-video.patch
File renamed without changes
Something went wrong with that request. Please try again.