[packages/qt4] - bumped icu version to 52 - added wkhtml patch (modifications from wkhtmltopdf fork; on bcond only

qboosh qboosh at pld-linux.org
Mon Oct 21 17:25:32 CEST 2013


commit 3583d8d70a3b67403433a8664d9f7facad0e1277
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date:   Mon Oct 21 17:24:57 2013 +0200

    - bumped icu version to 52
    - added wkhtml patch (modifications from wkhtmltopdf fork; on bcond only because it affects libQtGui ABI)

 qt4-wkhtml.patch | 2948 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qt4.spec         |   32 +-
 2 files changed, 2966 insertions(+), 14 deletions(-)
---
diff --git a/qt4.spec b/qt4.spec
index 2fbf1ca..a406bac 100644
--- a/qt4.spec
+++ b/qt4.spec
@@ -5,18 +5,22 @@
 #	- check Qt ui tool
 #
 # Conditional build:
-%bcond_with	nas		# enable NAS audio support
 %bcond_without	static_libs	# don't build static libraries
-%bcond_without	cups		# disable CUPS support
-%bcond_without	mysql		# don't build MySQL plugin
-%bcond_without	odbc		# don't build unixODBC plugin
-%bcond_without	pgsql		# don't build PostgreSQL plugin
-%bcond_without	sqlite3		# don't build SQLite3 plugin
-%bcond_without	sqlite		# don't build SQLite2 plugin
-%bcond_without	ibase		# don't build ibase (InterBase/Firebird) plugin
-%bcond_without	pch		# disable pch in qmake
-%bcond_without	gtk		# don't build GTK theme integration
-%bcond_without	system_phonon	# don't build phonon libraries
+# -- features
+%bcond_without	cups		# CUPS printing support
+%bcond_with	nas		# NAS audio support
+%bcond_without	gtk		# GTK+ theme integration
+%bcond_without	pch		# pch (pre-compiled headers) in qmake
+%bcond_without	system_phonon	# phonon libraries from phonon.spec intead of qt4.spec
+%bcond_with	wkhtml		# WKHTMLTOPDF patch (affects QtGui ABI)
+# -- databases
+%bcond_without	mysql		# MySQL plugin
+%bcond_without	odbc		# unixODBC plugin
+%bcond_without	pgsql		# PostgreSQL plugin
+%bcond_without	sqlite3		# SQLite3 plugin
+%bcond_without	sqlite		# SQLite2 plugin
+%bcond_without	ibase		# ibase (InterBase/Firebird) plugin
+# -- SIMD CPU instructions
 %bcond_with	mmx		# use MMX instructions
 %bcond_with	3dnow		# use 3Dnow instructions
 %bcond_with	sse		# use SSE instructions in gui/painting module
@@ -46,7 +50,7 @@
 %define		_withsql	1
 %{!?with_sqlite3:%{!?with_sqlite:%{!?with_ibase:%{!?with_mysql:%{!?with_pgsql:%{!?with_odbc:%undefine _withsql}}}}}}
 
-%define		icu_abi		49
+%define		icu_abi		52
 %define		next_icu_abi	%(echo $((%{icu_abi} + 1)))
 
 Summary:	The Qt GUI application framework
@@ -80,7 +84,7 @@ Patch7:		%{name}-x11_fonts.patch
 Patch8:		%{name}-ibase.patch
 Patch9:		qt-x11-opensource-src-4.5.1-enable_ft_lcdfilter.patch
 Patch10:	webkit-no_Werror.patch
-
+Patch11:	%{name}-wkhtml.patch
 Patch12:	fix-crash-in-assistant.patch
 Patch13:	improve-cups-support.patch
 # backported from Qt5 (essentially)
@@ -1470,7 +1474,7 @@ Programas exemplo para o Qt versão.
 %patch8 -p1
 %patch9 -p1
 %patch10 -p1
-
+%{?with_wkhtml:%patch11 -p1}
 %patch12 -p1
 %patch13 -p1
 
diff --git a/qt4-wkhtml.patch b/qt4-wkhtml.patch
new file mode 100644
index 0000000..85eaa00
--- /dev/null
+++ b/qt4-wkhtml.patch
@@ -0,0 +1,2948 @@
+git clone git://gitorious.org/~antialize/qt/antializes-qt.git, then checkout 4.8.4
+# check 4.8.4 commit ID on git://gitorious.org/qt/qt.git
+git diff 96311def2466dd44de64d77a1c815b22fbf68f71
+# parts related to static QtWebkit build are disabled
+
+#diff --git a/configure b/configure
+#index e3d464b..114933e 100755
+#--- a/configure
+#+++ b/configure
+#@@ -7749,12 +7749,12 @@ if [ "$CFG_GUI" = "no" ]; then
+#     canBuildWebKit="no"
+# fi
+# 
+#-if [ "$CFG_SHARED" = "no" ]; then
+#-    echo
+#-    echo "WARNING: Using static linking will disable the WebKit module."
+#-    echo
+#-    canBuildWebKit="no"
+#-fi
+#+#if [ "$CFG_SHARED" = "no" ]; then
+#+   # echo
+#+   # echo "WARNING: Using static linking will disable the WebKit module."
+#+   # echo
+#+   # canBuildWebKit="no"
+#+#fi
+# 
+# CFG_CONCURRENT="yes"
+# if [ "$canBuildQtConcurrent" = "no" ]; then
+#diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro b/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro
+#index a109179..146cb2d 100644
+#--- a/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro
+#+++ b/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro
+#@@ -217,6 +217,12 @@ symbian: {
+#     QMAKE_CXXFLAGS.ARMCC += -OTime -O3
+# }
+# 
+#+static {
+#+  !isEmpty(INSTALL_LIBS): target.path = $$INSTALL_LIBS
+#+  else: target.path = $$[QT_INSTALL_LIBS]
+#+  INSTALLS += target
+#+}
+#+
+# lessThan(QT_GCC_MAJOR_VERSION, 5) {
+#     # GCC 4.5 and before
+#     lessThan(QT_GCC_MINOR_VERSION, 6) {
+diff --git a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
+index ef72fb7..54ff69c 100644
+--- a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
+@@ -1080,7 +1080,9 @@ void FrameView::adjustMediaTypeForPrinting(bool printing)
+     if (printing) {
+         if (m_mediaTypeWhenNotPrinting.isNull())
+             m_mediaTypeWhenNotPrinting = mediaType();
+-            setMediaType("print");
++
++        String mediaType = (m_frame && m_frame->settings())?m_frame->settings()->printingMediaType():"print";
++        setMediaType(mediaType);
+     } else {
+         if (!m_mediaTypeWhenNotPrinting.isNull())
+             setMediaType(m_mediaTypeWhenNotPrinting);
+diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
+index 660ad11..8dffd52 100644
+--- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
+@@ -26,6 +26,7 @@
+ #include "FrameView.h"
+ #include "RenderLayer.h"
+ #include "RenderView.h"
++#include "Settings.h"
+ #include <wtf/text/StringConcatenate.h>
+ 
+ namespace WebCore {
+@@ -182,11 +183,21 @@ void PrintContext::begin(float width, float height)
+     // This function can be called multiple times to adjust printing parameters without going back to screen mode.
+     m_isPrinting = true;
+ 
+-    float minLayoutWidth = width * printingMinimumShrinkFactor;
+-    float minLayoutHeight = height * printingMinimumShrinkFactor;
++    float minimumShrinkFactor = m_frame->settings() ? 
++        m_frame->settings()->printingMinimumShrinkFactor() : 0.0f;
++    float maximumShrinkFactor = m_frame->settings() ? 
++        m_frame->settings()->printingMaximumShrinkFactor() : 0.0f;
++
++    if (maximumShrinkFactor < minimumShrinkFactor || minimumShrinkFactor <= 0.0f) {
++        minimumShrinkFactor = printingMinimumShrinkFactor;
++        maximumShrinkFactor = printingMaximumShrinkFactor;
++    }
++    
++    float minLayoutWidth = width * minimumShrinkFactor;
++    float minLayoutHeight = height * minimumShrinkFactor;
+ 
+     // This changes layout, so callers need to make sure that they don't paint to screen while in printing mode.
+-    m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), printingMaximumShrinkFactor / printingMinimumShrinkFactor, Frame::AdjustViewSize);
++    m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), maximumShrinkFactor / minimumShrinkFactor, Frame::AdjustViewSize);
+ }
+ 
+ float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize)
+diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
+index aadff47..19f378e 100644
+--- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
++++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
+@@ -83,6 +83,8 @@ public:
+     // (pageSizeInPixels.height() + 1) * number-of-pages - 1
+     static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels);
+ 
++public:
++    const Vector<IntRect> & getPageRects() const {return m_pageRects;}
+ protected:
+     Frame* m_frame;
+     Vector<IntRect> m_pageRects;
+diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
+index 2025bd0..5414246 100644
+--- a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
+@@ -87,6 +87,7 @@ static EditingBehaviorType editingBehaviorTypeForPlatform()
+ 
+ Settings::Settings(Page* page)
+     : m_page(page)
++    , m_printingMediaType("print")
+     , m_editableLinkBehavior(EditableLinkDefaultBehavior)
+     , m_textDirectionSubmenuInclusionBehavior(TextDirectionSubmenuAutomaticallyIncluded)
+     , m_passwordEchoDurationInSeconds(1)
+@@ -184,6 +185,8 @@ Settings::Settings(Page* page)
+     , m_allowDisplayOfInsecureContent(true)
+     , m_allowRunningOfInsecureContent(true)
+     , m_passwordEchoEnabled(false)
++    , m_printingMinimumShrinkFactor(0.0)
++    , m_printingMaximumShrinkFactor(0.0)
+ {
+     // A Frame may not have been created yet, so we initialize the AtomicString 
+     // hash before trying to use it.
+@@ -569,6 +572,11 @@ void Settings::setApplicationChromeMode(bool mode)
+     m_inApplicationChromeMode = mode;
+ }
+ 
++void Settings::setPrintingMediaType(const String& type)
++{
++    m_printingMediaType = type;
++}
++
+ void Settings::setOfflineWebApplicationCacheEnabled(bool enabled)
+ {
+     m_offlineWebApplicationCacheEnabled = enabled;
+@@ -744,4 +752,15 @@ void Settings::setTiledBackingStoreEnabled(bool enabled)
+ #endif
+ }
+ 
++void Settings::setPrintingMinimumShrinkFactor(float printingMinimumShrinkFactor)
++{
++    m_printingMinimumShrinkFactor = printingMinimumShrinkFactor;
++}    
++
++void Settings::setPrintingMaximumShrinkFactor(float printingMaximumShrinkFactor)
++{
++    m_printingMaximumShrinkFactor = printingMaximumShrinkFactor;
++}    
++
++
+ } // namespace WebCore
+diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.h b/src/3rdparty/webkit/Source/WebCore/page/Settings.h
+index 1d2a138..d827693 100644
+--- a/src/3rdparty/webkit/Source/WebCore/page/Settings.h
++++ b/src/3rdparty/webkit/Source/WebCore/page/Settings.h
+@@ -258,6 +258,9 @@ namespace WebCore {
+         void setApplicationChromeMode(bool);
+         bool inApplicationChromeMode() const { return m_inApplicationChromeMode; }
+ 
++        void setPrintingMediaType(const String&);
++        const String& printingMediaType() const { return m_printingMediaType; }
++
+         void setOfflineWebApplicationCacheEnabled(bool);
+         bool offlineWebApplicationCacheEnabled() const { return m_offlineWebApplicationCacheEnabled; }
+ 
+@@ -349,6 +352,12 @@ namespace WebCore {
+         
+         void setTiledBackingStoreEnabled(bool);
+         bool tiledBackingStoreEnabled() const { return m_tiledBackingStoreEnabled; }
++	
++        void setPrintingMinimumShrinkFactor(float);
++        float printingMinimumShrinkFactor() const { return m_printingMinimumShrinkFactor; }
++	
++        void setPrintingMaximumShrinkFactor(float);
++        float printingMaximumShrinkFactor() const { return m_printingMaximumShrinkFactor; }
+ 
+         void setPaginateDuringLayoutEnabled(bool flag) { m_paginateDuringLayoutEnabled = flag; }
+         bool paginateDuringLayoutEnabled() const { return m_paginateDuringLayoutEnabled; }
+@@ -419,6 +428,7 @@ namespace WebCore {
+         String m_defaultTextEncodingName;
+         String m_ftpDirectoryTemplatePath;
+         String m_localStorageDatabasePath;
++        String m_printingMediaType;
+         KURL m_userStyleSheetLocation;
+         AtomicString m_standardFontFamily;
+         AtomicString m_fixedFontFamily;
+@@ -429,6 +439,8 @@ namespace WebCore {
+         EditableLinkBehavior m_editableLinkBehavior;
+         TextDirectionSubmenuInclusionBehavior m_textDirectionSubmenuInclusionBehavior;
+         double m_passwordEchoDurationInSeconds;
++        float m_printingMinimumShrinkFactor;
++        float m_printingMaximumShrinkFactor;
+         int m_minimumFontSize;
+         int m_minimumLogicalFontSize;
+         int m_defaultFontSize;
+diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
+index c348870..4069687 100644
+--- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
+@@ -73,7 +73,8 @@ FontPlatformData::FontPlatformData(const FontDescription& description, const Ato
+     font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing);
+     const bool smallCaps = description.smallCaps();
+     font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase);
+-    font.setStyleStrategy(QFont::ForceIntegerMetrics);
++    // Commented out to work around webkit bug 93263
++    //font.setStyleStrategy(QFont::ForceIntegerMetrics);
+ 
+     m_data->bold = font.bold();
+     // WebKit allows font size zero but QFont does not. We will return
+diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
+index 0c8ce9e..5ba54d0 100644
+--- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
+@@ -41,6 +41,7 @@
+ #include "PlatformString.h"
+ #include "StillImageQt.h"
+ #include "qwebsettings.h"
++#include "SharedBuffer.h"
+ 
+ #include <QPixmap>
+ #include <QPainter>
+@@ -234,7 +235,8 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
+         }
+     }
+ 
+-    ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc);
++    QByteArray a = QByteArray::fromRawData(data()->data(), data()->size());
++    ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc, &a);
+ 
+     ctxt->setCompositeOperation(previousOperator);
+ 
+diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
+index 4db8bd1..0f405cb 100644
+--- a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
+@@ -53,11 +53,17 @@ static int screenNumber(Widget* w)
+ 
+ int screenDepth(Widget* w)
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return 32;
++
+     return QApplication::desktop()->screen(screenNumber(w))->depth();
+ }
+ 
+ int screenDepthPerComponent(Widget* w)
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return 8;
++
+     int depth = QApplication::desktop()->screen(0)->depth();
+     if (w) {
+         QWebPageClient* client = w->root()->hostWindow()->platformPageClient();
+@@ -86,17 +92,26 @@ int screenDepthPerComponent(Widget* w)
+ 
+ bool screenIsMonochrome(Widget* w)
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return false;
++
+     return QApplication::desktop()->screen(screenNumber(w))->colorCount() == 2;
+ }
+ 
+ FloatRect screenRect(Widget* w)
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return FloatRect(0,0,800,600);
++
+     QRect r = QApplication::desktop()->screenGeometry(screenNumber(w));
+     return FloatRect(r.x(), r.y(), r.width(), r.height());
+ }
+ 
+ FloatRect screenAvailableRect(Widget* w)
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return FloatRect(0,0,800,600);
++
+     QRect r = QApplication::desktop()->availableGeometry(screenNumber(w));
+     return FloatRect(r.x(), r.y(), r.width(), r.height());
+ }
+diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
+index f98df88..b1fe30d 100644
+--- a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
+@@ -178,7 +178,13 @@ RenderThemeQt::RenderThemeQt(Page* page)
+     : RenderTheme()
+     , m_page(page)
+     , m_lineEdit(0)
++    , m_fallbackStyle(0)
+ {
++    if (QApplication::type() == QApplication::Tty) {
++        m_buttonFontFamily = "sans-serif";
++        return;
++    }
++
+     QPushButton button;
+     button.setAttribute(Qt::WA_MacSmallSize);
+     QFont defaultButtonFont = QApplication::font(&button);
+@@ -339,6 +345,9 @@ bool RenderThemeQt::supportsControlTints() const
+ 
+ int RenderThemeQt::findFrameLineWidth(QStyle* style) const
+ {
++    if (QApplication::type()==QApplication::Tty)
++        return 1;
++
+ #ifndef QT_NO_LINEEDIT
+     if (!m_lineEdit)
+         m_lineEdit = new QLineEdit();
+@@ -445,6 +454,9 @@ Color RenderThemeQt::systemColor(int cssValueId) const
+ 
+ int RenderThemeQt::minimumMenuListSize(RenderStyle*) const
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return 1;
++
+     const QFontMetrics &fm = QApplication::fontMetrics();
+     return fm.width(QLatin1Char('x'));
+ }
+diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
+index d648c53..f844d54 100644
+--- a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
+@@ -54,6 +54,9 @@ static QWidget* qwidgetForPage(const Page* page)
+ 
+ FloatRect screenRect(const Page* page)
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return FloatRect(0,0,800,600);
++
+     QWidget* qw = qwidgetForPage(page);
+     if (!qw)
+         return FloatRect();
+@@ -68,6 +71,9 @@ FloatRect screenRect(const Page* page)
+ 
+ int screenDepth(const Page* page)
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return 32;
++
+     QWidget* qw = qwidgetForPage(page);
+     if (!qw)
+         return 32;
+@@ -77,6 +83,9 @@ int screenDepth(const Page* page)
+ 
+ FloatRect usableScreenRect(const Page* page)
+ {
++    if (QApplication::type() == QApplication::Tty)
++        return FloatRect();
++
+     QWidget* qw = qwidgetForPage(page);
+     if (!qw)
+         return FloatRect();
+diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
+index 5215e66..e033279 100644
+--- a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
+@@ -41,6 +41,7 @@
+ #include "QWebPageClient.h"
+ #include "ScrollView.h"
+ 
++#include <QApplication>
+ #include <QCoreApplication>
+ #include <QDebug>
+ #include <QPaintEngine>
+@@ -78,6 +79,9 @@ void Widget::setFocus(bool focused)
+ void Widget::setCursor(const Cursor& cursor)
+ {
+ #ifndef QT_NO_CURSOR
++    if (QApplication::type() == QApplication::Tty)
++        return;
++
+     ScrollView* view = root();
+     if (!view)
+         return;
+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/RenderBox.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
+index f052ee7..a5afea5 100644
+--- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
++++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
+@@ -804,7 +804,8 @@ void RenderBox::paintRootBoxFillLayers(const PaintInfo& paintInfo)
+ 
+     // The background of the box generated by the root element covers the entire canvas, so just use
+     // the RenderView's docTop/Left/Width/Height accessors.
+-    paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), BackgroundBleedNone, CompositeSourceOver, bodyObject);
++    if (bgColor.rgb() != Color::white)
++        paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), BackgroundBleedNone, CompositeSourceOver, bodyObject);
+ }
+ 
+ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
+diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
+index 73b0801..c34b1c2 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());
+@@ -320,6 +329,30 @@ void RenderTable::layout()
+     if (m_caption)
+         m_caption->layoutIfNeeded();
+ 
++    // Bump table to next page if we can't fit the caption, thead and first body cell
++    setPaginationStrut(0);
++    if (view()->layoutState()->pageLogicalHeight()) {
++        LayoutState* layoutState = view()->layoutState();
++        const int pageLogicalHeight = layoutState->m_pageLogicalHeight;
++        const int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(0) % pageLogicalHeight;
++        if (remainingLogicalHeight > 0) {
++            int requiredHeight = headHeight;
++            if (m_caption && m_caption->style()->captionSide() != CAPBOTTOM) {
++                requiredHeight += m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter();
++            }
++            if (m_firstBody) {
++                // FIXME: Calculate maximum required height across all cells in first body row
++                RenderTableCell* firstCell = m_firstBody->primaryCellAt(0, 0);
++                if (firstCell) {
++                    requiredHeight += firstCell->contentLogicalHeight() + firstCell->paddingTop(false) + firstCell->paddingBottom(false) + vBorderSpacing();
++                }
++            }
++            if (requiredHeight > remainingLogicalHeight) {
++                setPaginationStrut(remainingLogicalHeight);
++            }
++        }
++    }
++
+     // If any table section moved vertically, we will just repaint everything from that
+     // section down (it is quite unlikely that any of the following sections
+     // did not shift).
+@@ -352,12 +385,6 @@ void RenderTable::layout()
+         computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength);
+     computedLogicalHeight = max(0, computedLogicalHeight);
+ 
+-    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);
+-    }
+-
+     if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
+         // Completely empty tables (with no sections or anything) should at least honor specified height
+         // in strict mode.
+@@ -377,6 +404,9 @@ void RenderTable::layout()
+         }
+         section->setLogicalLocation(sectionLogicalLeft, logicalHeight());
+ 
++        // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one.
++        section->layoutRows(section == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0, section == m_head ? 0 : headHeight, section == m_foot ? 0 : footHeight);
++
+         setLogicalHeight(logicalHeight() + section->logicalHeight());
+         section = sectionBelow(section);
+     }
+@@ -503,7 +533,59 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
+             child->paint(info, childPoint.x(), childPoint.y());
+         }
+     }
+-    
++
++    bool repaintedHead = false;
++    IntPoint repaintedHeadPoint;
++    bool repaintedFoot = false;
++    IntPoint repaintedFootPoint;
++    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.y() > childPoint.y() + m_head->y()) {
++                repaintedHeadPoint = IntPoint(childPoint.x(), info.rect.y() - m_head->y());
++                repaintedHead = true;
++                dynamic_cast<RenderObject*>(m_head)->paint(info, repaintedHeadPoint.x(), repaintedHeadPoint.y());
++            }
++        }
++        if (m_foot) {
++            IntPoint childPoint = flipForWritingMode(m_foot, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
++            if (info.rect.y() + info.rect.height() < 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++;
++                        }
++                    }
++                }
++                repaintedFoot = true;
++                repaintedFootPoint = IntPoint(childPoint.x(), dy - m_foot->y());
++                dynamic_cast<RenderObject*>(m_foot)->paint(info, repaintedFootPoint.x(), repaintedFootPoint.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
+@@ -522,6 +604,12 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
+             for (RenderObject* child = firstChild(); child; child = child->nextSibling())
+                 if (child->isTableSection()) {
+                     IntPoint childPoint = flipForWritingMode(toRenderTableSection(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
++                    // also repaint borders of header/footer if required
++                    if (child == m_head && repaintedHead) {
++                        childPoint = repaintedHeadPoint;
++                    } else if (child == m_foot && repaintedFoot) {
++                        childPoint = repaintedFootPoint;
++                    }
+                     child->paint(info, childPoint.x(), childPoint.y());
+                 }
+         }
+diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
+index 7d414a0..6c814b3 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,47 @@ int RenderTableSection::layoutRows(int toAdd)
+ 
+     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
+ 
++    // Calculate logical row heights
++    Vector<int> logicalRowHeights;
++    logicalRowHeights.resize(totalRows);
++    for (int r = 0; r < totalRows; r++) {
++        logicalRowHeights[r] = m_rowPos[r + 1] - m_rowPos[r] - vspacing;
++    }
++
++    // Make sure that cell contents do not overlap a page break
++    if (view()->layoutState()->pageLogicalHeight()) {
++        LayoutState* layoutState = view()->layoutState();
++        int pageLogicalHeight = layoutState->m_pageLogicalHeight;
++        int pageOffset = 0;
++
++        for (int r = 0; r < totalRows; ++r) {
++            int rowLogicalOffset = m_rowPos[r] + pageOffset;
++            int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(rowLogicalOffset) % pageLogicalHeight;
++
++            for (int c = 0; c < nEffCols; c++) {
++                CellStruct& cs = cellAt(r, c);
++                RenderTableCell* cell = cs.primaryCell();
++
++                if (!cell || cs.inColSpan || cell->row() != r)
++                    continue;
++
++                int cellRequiredHeight = cell->contentLogicalHeight() + cell->paddingTop(false) + cell->paddingBottom(false);
++                if (max(logicalRowHeights[r], cellRequiredHeight) > remainingLogicalHeight - footHeight - vspacing) {
++                    pageOffset += remainingLogicalHeight + headHeight;
++                    break;
++                }
++            }
++            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);
++            rowRenderer->setLogicalHeight(logicalRowHeights[r]);
+             rowRenderer->updateLayerTransform();
+         }
+ 
+@@ -513,7 +548,11 @@ int RenderTableSection::layoutRows(int toAdd)
+                 continue;
+ 
+             rindx = cell->row();
+-            rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
++            if (cell->rowSpan() == 1) {
++                rHeight = logicalRowHeights[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()); }
+ 
+diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
+index 4b1a758..2ad7f1f 100644
+--- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
+@@ -170,6 +170,7 @@ private:
+     friend class QWebHitTestResult;
+     friend class QWebHitTestResultPrivate;
+     friend class QWebPage;
++    friend class QWebPrinter;
+ 
+ #if defined(WTF_USE_V8) && WTF_USE_V8
+     friend class V8::Bindings::QtWebElementRuntime;
+diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
+index 5ea7059..b0229ed 100644
+--- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
+@@ -216,6 +216,114 @@ static inline ResourceRequestCachePolicy cacheLoadControlToCachePolicy(uint cach
+     return WebCore::UseProtocolCachePolicy;
+ }
+ 
++#ifndef QT_NO_PRINTER
++QWebPrinterPrivate::QWebPrinterPrivate(const QWebFrame *f, QPaintDevice *printer, QPainter &p)
++    : printContext(f->d->frame)
++    , painter(p)
++    , frame(f)
++    , graphicsContext(&p)
++{
++    const qreal zoomFactorX = printer->logicalDpiX() / qt_defaultDpi();
++    const qreal zoomFactorY = printer->logicalDpiY() / qt_defaultDpi();
++    IntRect pageRect(0, 0,
++                     int(printer->width() / zoomFactorX),
++                     int(printer->height() / zoomFactorY));
++    
++    printContext.begin(pageRect.width(), pageRect.height());
++    float pageHeight = 0;
++    printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight);
++    
++    painter.scale(zoomFactorX, zoomFactorY);
++    printWidth = pageRect.width();
++}
++
++QWebPrinterPrivate::~QWebPrinterPrivate() 
++{
++    printContext.end();
++}
++
++/*!
++    \class QWebPrinter
++    \since 4.7
++    \brief The QWebPrinter controls printing of a \l{QWebFrame::}
++
++    \inmodule QtWebKit
++
++    \sa QWebFrame
++*/
++QWebPrinter::QWebPrinter(const QWebFrame *frame, QPaintDevice *printer, QPainter &painter)
++    : d(new QWebPrinterPrivate(frame, printer, painter))
++{}
++
++QWebPrinter::~QWebPrinter() 
++{
++    delete d; 
++}
++
++/*!
++    Print a page of the frame. \a i is  the number of the page to print, 
++    and must be between 1 and \fn QWebPrinter::pageCount() .
++*/
++void QWebPrinter::spoolPage(int i) const
++{
++    if (i < 1 || i > d->printContext.pageCount()) 
++        return;
++    d->printContext.spoolPage(d->graphicsContext, i - 1, d->printWidth);
++}
++
++/*!
++    Returns the number of pages of the frame when printed.
++*/
++int QWebPrinter::pageCount() const
++{
++    return d->printContext.pageCount();
++}
++
++QPair<int, QRectF> QWebPrinter::elementLocation(const QWebElement & e)
++{
++    //Compute a mapping from node to render object once and for all
++    if (d->elementToRenderObject.empty())
++	for (WebCore::RenderObject * o=d->frame->d->frame->document()->renderer(); o; o=o->nextInPreOrder())
++	    if (o->node())
++		d->elementToRenderObject[o->node()] = o;
++        
++    if (!d->elementToRenderObject.contains(e.m_element))
++	return QPair<int,QRectF>(-1, QRectF());
++    const WebCore::RenderObject * ro = d->elementToRenderObject[e.m_element];
++    const Vector<IntRect> & pageRects = d->printContext.getPageRects();
++
++    WebCore::RenderView *root = toRenderView(d->frame->d->frame->document()->renderer());
++    //We need the scale factor, because pages are shrinked
++    float scale = (float)d->printWidth / (float)root->width();
++
++    QRectF r(const_cast<WebCore::RenderObject *>(ro)->absoluteBoundingBoxRect());
++    
++    int low=0;
++    int high=pageRects.size();
++    int c = r.y() + r.height() / 2;
++    while(low <= high) {
++	int m = (low+high)/2;
++	if(c < pageRects[m].y())
++	    high = m-1;
++	else if(c > pageRects[m].maxY())
++	    low = m +1;
++	else {
++	  QRectF tr = r.translated(0, -pageRects[m].y());
++	  return QPair<int, QRectF>(m+1, QRect(tr.x() * scale, tr.y()*scale, tr.width()*scale, tr.height()*scale));
++	}
++	 
++    }
++    return QPair<int,QRectF>(-1, QRectF());
++}
++
++/*!
++    Return the painter used for printing.
++*/
++QPainter * QWebPrinter::painter() {
++    return &d->painter;
++}
++#endif //QT_NO_PRINTER
++
+ QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame,
+                              WebCore::HTMLFrameOwnerElement* ownerFrameElement,
+                              const WTF::String& frameName)
+@@ -1434,25 +1542,8 @@ bool QWebFrame::event(QEvent *e)
+ void QWebFrame::print(QPrinter *printer) const
+ {
+     QPainter painter;
+-    if (!painter.begin(printer))
+-        return;
+-
+-    const qreal zoomFactorX = (qreal)printer->logicalDpiX() / qt_defaultDpi();
+-    const qreal zoomFactorY = (qreal)printer->logicalDpiY() / qt_defaultDpi();
+-
+-    PrintContext printContext(d->frame);
+-    float pageHeight = 0;
+-
+-    QRect qprinterRect = printer->pageRect();
+-
+-    IntRect pageRect(0, 0,
+-                     int(qprinterRect.width() / zoomFactorX),
+-                     int(qprinterRect.height() / zoomFactorY));
+-
+-    printContext.begin(pageRect.width());
+-
+-    printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight);
+-
++    painter.begin(printer);
++    QWebPrinter p(this, printer, painter);
+     int docCopies;
+     int pageCopies;
+     if (printer->collateCopies()) {
+@@ -1469,11 +1560,12 @@ void QWebFrame::print(QPrinter *printer) const
+ 
+     if (fromPage == 0 && toPage == 0) {
+         fromPage = 1;
+-        toPage = printContext.pageCount();
++        toPage = p.pageCount();
+     }
+     // paranoia check
+     fromPage = qMax(1, fromPage);
+-    toPage = qMin(static_cast<int>(printContext.pageCount()), toPage);
++    toPage = qMin(static_cast<int>(p.pageCount()), toPage);
++
+     if (toPage < fromPage) {
+         // if the user entered a page range outside the actual number
+         // of printable pages, just return
+@@ -1486,20 +1578,15 @@ void QWebFrame::print(QPrinter *printer) const
+         toPage = tmp;
+         ascending = false;
+     }
+-
+-    painter.scale(zoomFactorX, zoomFactorY);
+-    GraphicsContext ctx(&painter);
+-
+     for (int i = 0; i < docCopies; ++i) {
+         int page = fromPage;
+         while (true) {
+             for (int j = 0; j < pageCopies; ++j) {
+                 if (printer->printerState() == QPrinter::Aborted
+                     || printer->printerState() == QPrinter::Error) {
+-                    printContext.end();
+                     return;
+                 }
+-                printContext.spoolPage(ctx, page - 1, pageRect.width());
++                p.spoolPage(page);
+                 if (j < pageCopies - 1)
+                     printer->newPage();
+             }
+@@ -1518,8 +1605,7 @@ void QWebFrame::print(QPrinter *printer) const
+         if ( i < docCopies - 1)
+             printer->newPage();
+     }
+-
+-    printContext.end();
++    painter.end();
+ }
+ #endif // QT_NO_PRINTER
+ 
+diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
+index 3c5a28e..99771f8 100644
+--- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
+@@ -21,6 +21,8 @@
+ #ifndef QWEBFRAME_H
+ #define QWEBFRAME_H
+ 
++#define  __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
++
+ #include <QtCore/qobject.h>
+ #include <QtCore/qurl.h>
+ #include <QtCore/qvariant.h>
+@@ -42,6 +44,9 @@ class QPrinter;
+ QT_END_NAMESPACE
+ 
+ class QWebNetworkRequest;
++#ifndef QT_NO_PRINTER
++class QWebPrinterPrivate;
++#endif
+ class QWebFramePrivate;
+ class QWebPage;
+ class QWebHitTestResult;
+@@ -103,6 +108,20 @@ private:
+     friend class QWebPage;
+ };
+ 
++#ifndef QT_NO_PRINTER
++class QWEBKIT_EXPORT QWebPrinter {
++public:
++    QWebPrinter(const QWebFrame * frame, QPaintDevice * printer, QPainter &painter);
++    ~QWebPrinter();
++    void spoolPage(int i) const;
++    QPainter * painter();
++    int pageCount() const;
++    QPair<int, QRectF> elementLocation(const QWebElement & e);
++private:
++    QWebPrinterPrivate * d;
++};
++#endif
++
+ class QWEBKIT_EXPORT QWebFrame : public QObject {
+     Q_OBJECT
+     Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false)
+@@ -228,6 +247,8 @@ private:
+     friend class QWebPage;
+     friend class QWebPagePrivate;
+     friend class QWebFramePrivate;
++    friend class QWebPrinterPrivate;
++    friend class QWebPrinter;
+     friend class DumpRenderTreeSupportQt;
+     friend class WebCore::WidgetPrivate;
+     friend class WebCore::FrameLoaderClientQt;
+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..3698eed 100644
+--- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
+@@ -35,6 +35,9 @@
+ #include "wtf/RefPtr.h"
+ #include "Frame.h"
+ #include "ViewportArguments.h"
++#include <qpainter.h>
++#include "PrintContext.h"
++#include "GraphicsContext.h"
+ 
+ #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
+ #include "texmap/TextureMapper.h"
+@@ -69,6 +72,19 @@ public:
+     int marginHeight;
+ };
+ 
++class QWebPrinterPrivate {
++public:
++    WebCore::PrintContext printContext;
++    QPainter & painter;
++    const QWebFrame * frame;
++    WebCore::GraphicsContext graphicsContext;
++    int printWidth;
++    QHash<const WebCore::Node*, const WebCore::RenderObject *> elementToRenderObject;
++    
++    QWebPrinterPrivate(const QWebFrame * frame, QPaintDevice *printer, QPainter &p);
++    ~QWebPrinterPrivate();
++};
++
+ class QWebFramePrivate {
+ public:
+     QWebFramePrivate()
+diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
+index c1ef92e..dc4de39 100644
+--- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
+@@ -75,8 +75,11 @@ public:
+     QUrl userStyleSheetLocation;
+     QString defaultTextEncoding;
+     QString localStoragePath;
++    QString printingMediaType;
+     QString offlineWebApplicationCachePath;
+     qint64 offlineStorageDefaultQuota;
++    qreal printingMinimumShrinkFactor;
++    qreal printingMaximumShrinkFactor;
+ 
+     void apply();
+     WebCore::Settings* settings;
+@@ -229,9 +232,18 @@ void QWebSettingsPrivate::apply()
+         QString encoding = !defaultTextEncoding.isEmpty() ? defaultTextEncoding: global->defaultTextEncoding;
+         settings->setDefaultTextEncodingName(encoding);
+ 
++        QString type = !printingMediaType.isEmpty() ? printingMediaType : global->printingMediaType;
++        settings->setPrintingMediaType(type.isEmpty() ? "print" : type);
++
+         QString storagePath = !localStoragePath.isEmpty() ? localStoragePath : global->localStoragePath;
+         settings->setLocalStorageDatabasePath(storagePath);
+ 
++        float minimumShrinkFactor = printingMinimumShrinkFactor > 0.0f ? printingMinimumShrinkFactor : global->printingMinimumShrinkFactor;
++        settings->setPrintingMinimumShrinkFactor(minimumShrinkFactor);
++
++        float maximumShrinkFactor = printingMaximumShrinkFactor > 0.0f ? printingMaximumShrinkFactor : global->printingMaximumShrinkFactor;
++        settings->setPrintingMaximumShrinkFactor(maximumShrinkFactor);
++
+         value = attributes.value(QWebSettings::PrintElementBackgrounds,
+                                       global->attributes.value(QWebSettings::PrintElementBackgrounds));
+         settings->setShouldPrintBackgrounds(value);
+@@ -519,6 +531,8 @@ QWebSettings::QWebSettings()
+     d->attributes.insert(QWebSettings::SiteSpecificQuirksEnabled, true);
+     d->offlineStorageDefaultQuota = 5 * 1024 * 1024;
+     d->defaultTextEncoding = QLatin1String("iso-8859-1");
++    d->printingMinimumShrinkFactor = 1.25f;
++    d->printingMaximumShrinkFactor = 2.0f;
+ }
+ 
+ /*!
+@@ -527,6 +541,8 @@ QWebSettings::QWebSettings()
+ QWebSettings::QWebSettings(WebCore::Settings* settings)
+     : d(new QWebSettingsPrivate(settings))
+ {
++    d->printingMinimumShrinkFactor = 0.0f;
++    d->printingMaximumShrinkFactor = 0.0f;
+     d->settings = settings;
+     d->apply();
+     allSettings()->append(d);
+@@ -635,6 +651,86 @@ QString QWebSettings::defaultTextEncoding() const
+ }
+ 
+ /*!
++    \since 4.7
++    Specifies which media type to use when printing. If
++    left empty the default "print" will be used, other choices include "screen". 
++    See \l{http://www.w3.org/TR/CSS2/media.html}{CSS Standard}, for a complete list.
++
++    \sa printingMediaType()
++*/
++void QWebSettings::setPrintingMediaType(const QString& type)
++{
++    d->printingMediaType = type;
++    d->apply();
++}
++
++/*!
++    \since 4.7
++    Returns the media type used when printing or QString() if the
++    default value is used.
++
++    \sa setPrintingMediaType()
++*/
++QString QWebSettings::printingMediaType() const
++{
++    return d->printingMediaType;
++}
++
++/*!
++    \since 4.6
++    Specifies minimum shrink fator allowed for printing. If set to 0 a
++    default value is used.
++
++    When printing, content will be shrunk to reduce page usage, it
++    will reduced by a factor between printingMinimumShrinkFactor and
++    printingMaximumShrinkFactor. 
++
++    \sa printingMinimumShrinkFactor()
++    \sa setPrintingMaximumShrinkFactor()
++    \sa printingMaximumShrinkFactor()
++*/
++void QWebSettings::setPrintingMinimumShrinkFactor(qreal printingMinimumShrinkFactor)
++{
++    d->printingMinimumShrinkFactor = printingMinimumShrinkFactor;
++    d->apply();
++}
++
++/*!
++    \since 4.6
++    returns the minimum shrink factor used for printing.
++
++    \sa setPrintingMinimumShrinkFactor()
++*/
++qreal QWebSettings::printingMinimumShrinkFactor() const
++{
++    return d->printingMinimumShrinkFactor;
++}
++
++/*!
++    \since 4.6 
++    Specifies maximum shrink fator allowed for printing. If set to 0 a
++    default value is used.
++
++    \sa setPrintingMinimumShrinkFactor()
++*/
++void QWebSettings::setPrintingMaximumShrinkFactor(qreal printingMaximumShrinkFactor)
++{
++    d->printingMaximumShrinkFactor = printingMaximumShrinkFactor;
++    d->apply();
++}
++
++/*!
++    \since 4.6 
++    returns the maximum shrink factor used for printing.
++
++    \sa setPrintingMinimumShrinkFactor()
++*/
++qreal QWebSettings::printingMaximumShrinkFactor() const
++{
++    return d->printingMaximumShrinkFactor;
++}
++
++/*!
+     Sets the path of the icon database to \a path. The icon database is used
+     to store "favicons" associated with web sites.
+ 
+diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
+index 008035b..bb134a3 100644
+--- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
++++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
+@@ -116,6 +116,15 @@ public:
+     void setDefaultTextEncoding(const QString &encoding);
+     QString defaultTextEncoding() const;
+ 
++    void setPrintingMediaType(const QString &type);
++    QString printingMediaType() const;
++
++    void setPrintingMinimumShrinkFactor(qreal printingMinimumShrinkFactor);
++    qreal printingMinimumShrinkFactor() const;
++
++    void setPrintingMaximumShrinkFactor(qreal printingMaximimShrinkFactor);
++    qreal printingMaximumShrinkFactor() const;
++
+     static void setIconDatabasePath(const QString &location);
+     static QString iconDatabasePath();
+     static void clearIconDatabase();
+diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
+index 3fc65d3..6657879 100644
+--- a/src/gui/image/qpixmap.cpp
++++ b/src/gui/image/qpixmap.cpp
+@@ -134,12 +134,6 @@ extern QApplication::Type qt_appType;
+ 
+ void QPixmap::init(int w, int h, int type)
+ {
+-    if (qt_appType == QApplication::Tty) {
+-        qWarning("QPixmap: Cannot create a QPixmap when no GUI is being used");
+-        data = 0;
+-        return;
+-    }
+-
+     if ((w > 0 && h > 0) || type == QPixmapData::BitmapType)
+         data = QPixmapData::create(w, h, (QPixmapData::PixelType) type);
+     else
+diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
+index 5950c5d..36303a0 100644
+--- a/src/gui/image/qpixmap_raster.cpp
++++ b/src/gui/image/qpixmap_raster.cpp
+@@ -47,6 +47,7 @@
+ #include "qnativeimage_p.h"
+ #include "qimage_p.h"
+ #include "qpaintengine.h"
++#include "kernel/qapplication_p.h"
+ 
+ #include "qbitmap.h"
+ #include "qimage.h"
+@@ -115,8 +116,10 @@ void QRasterPixmapData::resize(int width, int height)
+ #else
+     if (pixelType() == BitmapType)
+         format = QImage::Format_MonoLSB;
+-    else
++    else if (qt_is_gui_used)
+         format = QNativeImage::systemFormat();
++    else
++        format = QImage::Format_RGB32;
+ #endif
+ 
+     image = QImage(width, height, format);
+@@ -431,7 +434,7 @@ void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConve
+                     ? QImage::Format_ARGB32_Premultiplied
+                     : QImage::Format_RGB32;
+         } else {
+-            QImage::Format opaqueFormat = QNativeImage::systemFormat();
++            QImage::Format opaqueFormat = qt_is_gui_used ? QNativeImage::systemFormat() : QImage::Format_RGB32;
+             QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
+ 
+ #if !defined(QT_HAVE_NEON) && !defined(QT_ALWAYS_HAVE_SSE2)
+diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
+index 9582abf..ebaea4b 100644
+--- a/src/gui/kernel/qapplication_x11.cpp
++++ b/src/gui/kernel/qapplication_x11.cpp
+@@ -2280,6 +2280,8 @@ void qt_init(QApplicationPrivate *priv, int,
+         QSegfaultHandler::initialize(priv->argv, priv->argc);
+ #endif
+         QCursorData::initialize();
++    } else if (!QApplicationPrivate::graphics_system_name.isNull()) {
++        QApplicationPrivate::graphics_system = QGraphicsSystemFactory::create(QApplicationPrivate::graphics_system_name);
+     }
+     QFont::initialize();
+ 
+diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
+index d8aefb6..37106f7 100644
+--- a/src/gui/kernel/qguiplatformplugin.cpp
++++ b/src/gui/kernel/qguiplatformplugin.cpp
+@@ -85,7 +85,7 @@ QGuiPlatformPlugin *qt_guiPlatformPlugin()
+ 
+         QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN"));
+ #ifdef Q_WS_X11
+-        if (key.isEmpty()) {
++        if (QApplication::type() != QApplication::Tty && key.isEmpty()) {
+             switch(X11->desktopEnvironment) {
+             case DE_KDE:
+                 key = QString::fromLatin1("kde");
+diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
+index cd7075e..74508b3 100644
+--- a/src/gui/painting/qpaintengine.h
++++ b/src/gui/painting/qpaintengine.h
+@@ -162,6 +162,19 @@ public:
+     virtual void drawRects(const QRect *rects, int rectCount);
+     virtual void drawRects(const QRectF *rects, int rectCount);
+ 
++    virtual void addHyperlink(const QRectF &r, const QUrl &url) {Q_UNUSED(r); Q_UNUSED(url);}
++    virtual void addAnchor(const QRectF &r, const QString &name) {Q_UNUSED(r); Q_UNUSED(name);}
++    virtual void addLink(const QRectF &r, const QString &anchor) {Q_UNUSED(r); Q_UNUSED(anchor);}
++    virtual void addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength) {
++        Q_UNUSED(r); Q_UNUSED(text); Q_UNUSED(name); Q_UNUSED(multiLine); Q_UNUSED(password); Q_UNUSED(readOnly); Q_UNUSED(maxLength);
++    }
++    virtual void addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) {
++        Q_UNUSED(r); Q_UNUSED(checked); Q_UNUSED(name); Q_UNUSED(readOnly);
++    }
++    virtual void addRadioButton(const QRectF &r, const QString & group="", bool checked=false, const QString &name="", bool readOnly=false) {
++        Q_UNUSED(r); Q_UNUSED(checked); Q_UNUSED(name); Q_UNUSED(readOnly); Q_UNUSED(group);
++    }
++
+     virtual void drawLines(const QLine *lines, int lineCount);
+     virtual void drawLines(const QLineF *lines, int lineCount);
+ 
+@@ -177,6 +190,10 @@ public:
+     virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
+ 
+     virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) = 0;
++    virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data) {
++		Q_UNUSED(data);
++		drawPixmap(r,pm,sr);
++	}
+     virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
+     virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+     virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
+diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
+index 10ca689..d690761 100644
+--- a/src/gui/painting/qpaintengine_raster.cpp
++++ b/src/gui/painting/qpaintengine_raster.cpp
+@@ -2243,11 +2243,11 @@ namespace {
+ /*!
+     \reimp
+ */
+-void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
++void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &_img, const QRectF &_sr,
+                                    Qt::ImageConversionFlags)
+ {
+ #ifdef QT_DEBUG_DRAW
+-    qDebug() << " - QRasterPaintEngine::drawImage(), r=" << r << " sr=" << sr << " image=" << img.size() << "depth=" << img.depth();
++    qDebug() << " - QRasterPaintEngine::drawImage(), r=" << r << " sr=" << _sr << " image=" << _img.size() << "depth=" << img.depth();
+ #endif
+ 
+     if (r.isEmpty())
+@@ -2255,6 +2255,17 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
+ 
+     Q_D(QRasterPaintEngine);
+     QRasterPaintEngineState *s = state();
++    
++    QImage img;
++    QRectF sr=_sr;
++    if (s->matrix.isAffine()) {
++        img = _img.copy(sr.toRect()).scaled(
++            s->matrix.mapRect(r).size().toSize(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
++        sr = img.rect();
++    } else {
++        img=_img;
++    }
++ 
+     int sr_l = qFloor(sr.left());
+     int sr_r = qCeil(sr.right()) - 1;
+     int sr_t = qFloor(sr.top());
+diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
+index 30f986d..7836b5a 100644
+--- a/src/gui/painting/qpainter.cpp
++++ b/src/gui/painting/qpainter.cpp
+@@ -5393,7 +5393,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
+     }
+ }
+ 
+-void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
++void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data)
+ {
+ #if defined QT_DEBUG_DRAW
+     if (qt_show_painter_debug_output)
+@@ -5518,7 +5518,7 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+             x += d->state->matrix.dx();
+             y += d->state->matrix.dy();
+         }
+-        d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
++        d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh), data);
+     }
+ }
+ 
+@@ -7254,6 +7254,200 @@ void QPainter::fillRect(const QRectF &r, const QColor &color)
+     \since 4.5
+ */
+ 
++
++/*!
++    \fn void QPainter::addAnchor(int x, int y, int w, int h, const QString &name);
++
++    \overload
++
++    Add an anchor to the current page at the rect specified by \a x, \a y, \a w and \a h  
++    named \a name.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \sa addLink()
++
++    \since 4.7
++*/
++
++/*!
++    \fn void QPainter::addAnchor(const QRect &r, const QString &name);
++
++    \overload
++
++    Add an anchor to the current page at the rect specified by \a r named \a name.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \sa addLink()
++
++    \since 4.7
++*/
++
++/*!
++    \fn void addAnchor(const QRectF &r, const QString &name);
++
++    \overload
++
++    Add an anchor to the current page at the rect specified by \a r named \a name.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \sa addLink()
++
++    \since 4.7
++*/
++void QPainter::addAnchor(const QRectF &r, const QString &name)
++{
++    Q_D(QPainter);
++    if (!d->engine) {
++        qWarning("QPainter::addAnchor: Painter not active");
++        return;
++    }
++    d->engine->addAnchor(worldTransform().mapRect(r), name);
++}
++
++/*!
++    \fn void QPainter::addLink(int x, int y, int w, int h, const QString &anchor);
++
++    \overload
++
++    Add a link to the current page at the rect specified by \a x, \a y, \a w and \a h  
++    linking to the anchor named \a anchor.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \sa addAnchor()
++
++    \since 4.7
++*/
++
++/*!
++    \fn void QPainter::addLink(const QRect &r, const QString &anchor);
++
++    \overload
++
++    Add a link to the current page at the rect specified by \a r  
++    linking to the anchor named \a anchor.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \sa addAnchor()
++
++    \since 4.7
++*/
++
++/*!
++    \fn void QPainter::addLink(const QRectF &r, const QString &anchor);
++
++    \overload
++
++    Add a link to the current page at the rect specified by \a r  
++    linking to the anchor named \a anchor.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \sa addAnchor()
++
++    \since 4.7
++*/
++void QPainter::addLink(const QRectF &r, const QString &anchor)
++{
++    Q_D(QPainter);
++    if (!d->engine) {
++        qWarning("QPainter::addLink: Painter not active");
++        return;
++    }
++    
++    d->engine->addLink(worldTransform().mapRect(r), anchor);
++}
++
++
++/*!
++    \fn void QPainter::addHyperlink(int x, int y, int w, int h, const QUrl &url);
++
++    \overload
++
++    Add a link to the current page at the rect specified by \a x, \a y, \a w and \a h  
++    linking to \a url.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \since 4.7
++*/
++
++/*!
++    \fn void QPainter::addHyperlink(const QRect &r, const QUrl &url);
++
++    \overload
++
++    Add a link to the current page at the rect specified by \a r
++    linking to \a url.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \since 4.7
++*/
++
++/*!
++    \fn void QPainter::addHyperlink(const QRectF &r, const QUrl &url);
++
++    \overload
++
++    Add a link to the current page at the rect specified by \a r
++    linking to \a url.
++
++    Note that for output formats not supporting links, currently all other then PDF,
++    this call has no effect.
++
++    \since 4.7
++*/
++void QPainter::addHyperlink(const QRectF &r, const QUrl &url)
++{
++    Q_D(QPainter);
++    if (!d->engine) {
++        qWarning("QPainter::addHyperlink: Painter not active");
++        return;
++    }
++    d->engine->addHyperlink(worldTransform().mapRect(r), url);
++}
++
++void QPainter::addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength) {
++    Q_D(QPainter);
++    if (!d->engine) {
++        qWarning("QPainter::addTextField: Painter not active");
++        return;
++    }
++    d->engine->addTextField(worldTransform().mapRect(r), text, name, multiLine, password, readOnly, maxLength);
++}
++
++void QPainter::addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) {
++    Q_D(QPainter);
++    if (!d->engine) {
++        qWarning("QPainter::addCheckBox: Painter not active");
++        return;
++    }
++    d->engine->addCheckBox(worldTransform().mapRect(r), checked, name, readOnly);
++}
++
++
++void QPainter::addRadioButton(const QRectF &r, const QString & group, bool checked, const QString &name, bool readOnly) {
++    Q_D(QPainter);
++    if (!d->engine) {
++        qWarning("QPainter::addRadioButton: Painter not active");
++        return;
++    }
++    d->engine->addRadioButton(worldTransform().mapRect(r), group, checked, name, readOnly);
++}
++
+ /*!
+     Sets the given render \a hint on the painter if \a on is true;
+     otherwise clears the render hint.
+diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
+index f0312e5..d853a9b 100644
+--- a/src/gui/painting/qpainter.h
++++ b/src/gui/painting/qpainter.h
+@@ -364,7 +364,7 @@ public:
+     inline void drawPicture(const QPoint &p, const QPicture &picture);
+ #endif
+ 
+-    void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect);
++    void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect, const QByteArray * data=0);
+     inline void drawPixmap(const QRect &targetRect, const QPixmap &pixmap, const QRect &sourceRect);
+     inline void drawPixmap(int x, int y, int w, int h, const QPixmap &pm,
+                            int sx, int sy, int sw, int sh);
+@@ -447,6 +447,22 @@ public:
+     inline void fillRect(const QRect &r, Qt::BrushStyle style);
+     inline void fillRect(const QRectF &r, Qt::BrushStyle style);
+ 
++    inline void addAnchor(int x, int y, int w, int h, const QString &name);
++    inline void addAnchor(const QRect &r, const QString &name);
++    void addAnchor(const QRectF &r, const QString &name);
++
++    inline void addLink(int x, int y, int w, int h, const QString &anchor);
++    inline void addLink(const QRect &r, const QString &anchor);
++    void addLink(const QRectF &r, const QString &anchor);
++    
++    void addTextField(const QRectF &r, const QString &text="", const QString &name="", bool multiLine=false, bool password=false, bool readOnly=false, int maxLength=-1);
++    void addCheckBox(const QRectF &r, bool checked=false, const QString &name="", bool readOnly=false);
++    void addRadioButton(const QRectF &r, const QString & group="",  bool checked=false, const QString &name="", bool readOnly=false);;
++
++    inline void addHyperlink(int x, int y, int w, int h, const QUrl &url);
++    inline void addHyperlink(const QRect &r, const QUrl &url);
++    void addHyperlink(const QRectF &r, const QUrl &url);
++    
+     void eraseRect(const QRectF &);
+     inline void eraseRect(int x, int y, int w, int h);
+     inline void eraseRect(const QRect &);
+@@ -821,6 +837,35 @@ inline void QPainter::fillRect(const QRectF &r, Qt::BrushStyle style)
+     fillRect(r, QBrush(style));
+ }
+ 
++inline void QPainter::addAnchor(int x, int y, int w, int h, const QString &name) 
++{
++    addAnchor(QRectF(x, y, w, h), name);
++}
++
++inline void QPainter::addAnchor(const QRect &r, const QString &name)
++{
++    addAnchor(QRectF(r), name);
++}
++
++inline void QPainter::addLink(int x, int y, int w, int h, const QString &anchor)
++{
++    addLink(QRectF(x, y, w, h), anchor);
++}
++
++inline void QPainter::addLink(const QRect &r, const QString &anchor)
++{
++    addLink(QRectF(r), anchor);
++}
++
++inline void QPainter::addHyperlink(int x, int y, int w, int h, const QUrl &url)
++{
++    addHyperlink(QRectF(x, y, w, h), url);
++}
++
++inline void QPainter::addHyperlink(const QRect &r, const QUrl &url)
++{
++    addHyperlink(QRectF(r), url);
++}
+ 
+ inline void QPainter::setBrushOrigin(int x, int y)
+ {
+diff --git a/src/gui/painting/qprintengine.h b/src/gui/painting/qprintengine.h
+index 83bbf96..809b51a 100644
+--- a/src/gui/painting/qprintengine.h
++++ b/src/gui/painting/qprintengine.h
+@@ -90,6 +90,9 @@ public:
+         PPK_SupportsMultipleCopies,
+         PPK_PaperSize = PPK_PageSize,
+ 
++        PPK_UseCompression,
++        PPK_ImageQuality, 
++        PPK_ImageDPI,
+         PPK_CustomBase = 0xff00
+     };
+ 
+@@ -97,6 +100,8 @@ public:
+     virtual QVariant property(PrintEnginePropertyKey key) const = 0;
+ 
+     virtual bool newPage() = 0;
++    virtual void beginSectionOutline(const QString &text, const QString &anchor) {Q_UNUSED(text); Q_UNUSED(anchor);}
++    virtual void endSectionOutline() {}
+     virtual bool abort() = 0;
+ 
+     virtual int metric(QPaintDevice::PaintDeviceMetric) const = 0;
+diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
+index 239a94f..36eec2e 100644
+--- a/src/gui/painting/qprintengine_pdf.cpp
++++ b/src/gui/painting/qprintengine_pdf.cpp
+@@ -51,6 +51,7 @@
+ #include <qimagewriter.h>
+ #include <qbuffer.h>
+ #include <qdatetime.h>
++#include <QCryptographicHash>
+ 
+ #ifndef QT_NO_PRINTER
+ #include <limits.h>
+@@ -77,12 +78,6 @@ extern qint64 qt_image_id(const QImage &image);
+ // Can't use it though, as gs generates completely wrong images if this is true.
+ static const bool interpolateImages = false;
+ 
+-#ifdef QT_NO_COMPRESS
+-static const bool do_compress = false;
+-#else
+-static const bool do_compress = true;
+-#endif
+-
+ QPdfPage::QPdfPage()
+     : QPdf::ByteStream(true) // Enable file backing
+ {
+@@ -109,6 +104,30 @@ inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()
+     return f;
+ }
+ 
++void QPdfEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) {
++    Q_D(QPdfEngine);
++    if (key==PPK_UseCompression)
++        d->doCompress = value.toBool();
++    else if (key==PPK_ImageQuality)
++        d->imageQuality = value.toInt();
++    else if (key==PPK_ImageDPI)
++        d->imageDPI = value.toInt();
++    else 
++        QPdfBaseEngine::setProperty(key, value);
++}
++
++QVariant QPdfEngine::property(PrintEnginePropertyKey key) const {
++    Q_D(const QPdfEngine);
++    if (key==PPK_UseCompression)
++        return d->doCompress;
++    else if (key==PPK_ImageQuality)
++        return d->imageQuality;
++    else if (key==PPK_ImageDPI)
++        return d->imageDPI;
++    else
++        return QPdfBaseEngine::property(key);
++}
++
+ QPdfEngine::QPdfEngine(QPrinter::PrinterMode m)
+     : QPdfBaseEngine(*new QPdfEnginePrivate(m), qt_pdf_decide_features())
+ {
+@@ -156,6 +175,59 @@ bool QPdfEngine::begin(QPaintDevice *pdev)
+ bool QPdfEngine::end()
+ {
+     Q_D(QPdfEngine);
++	
++    uint dests;
++    if (d->anchors.size()) {
++        dests = d->addXrefEntry(-1);
++        d->xprintf("<<\n");
++        for (QHash<QString, uint>::iterator i=d->anchors.begin();
++             i != d->anchors.end(); ++i) {
++            d->printAnchor(i.key());
++            d->xprintf(" %d 0 R\n", i.value());
++        }
++        d->xprintf(">>\n");
++    }	
++
++    if (d->outlineRoot) {
++        d->outlineRoot->obj = d->requestObject();
++        d->writeOutlineChildren(d->outlineRoot);
++        d->addXrefEntry(d->outlineRoot->obj);
++        d->xprintf("<</Type /Outlines /First %d 0 R\n/Last %d 0 R>>\nendobj\n",
++                   d->outlineRoot->firstChild->obj, d->outlineRoot->lastChild->obj);
++    }
++    
++    if (d->formFields.size()) {
++        uint font = d->addXrefEntry(-1);
++        d->xprintf("<</Type/Font/Name/Helv/BaseFont/Helvetica/Subtype/Type1>>\n"
++                   "endobj\n");
++        d->addXrefEntry(d->formFieldList);
++        d->xprintf("<</Fields[");
++        foreach(const uint & i, d->formFields)
++           d->xprintf("%d 0 R ",i);
++        d->xprintf("]\n"
++                   "/DR<</Font<</Helv %d 0 R>>>>\n"
++                   "/DA(/Helv 0 Tf 0 g)\n"
++                   ">>\n"
++                   "endobj\n", font);
++    }
++
++    d->catalog = d->addXrefEntry(-1);
++    d->xprintf("<<\n"
++               "/Type /Catalog\n"
++               "/Pages %d 0 R\n", d->pageRoot);
++    if (d->outlineRoot)
++        d->xprintf("/Outlines %d 0 R\n"
++                   "/PageMode /UseOutlines\n", d->outlineRoot->obj);
++
++    if (d->formFields.size()) 
++        d->xprintf("/AcroForm %d 0 R\n", d->formFieldList);
++
++    if (d->anchors.size())
++        d->xprintf("/Dests %d 0 R\n", dests);
++
++    d->xprintf(">>\n"
++               "endobj\n");
++
+     d->writeTail();
+ 
+     d->stream->unsetDevice();
+@@ -165,8 +237,83 @@ bool QPdfEngine::end()
+     return true;
+ }
+ 
++void QPdfEngine::addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) {
++    Q_D(QPdfEngine);
++    uint obj = d->addXrefEntry(-1);
++    char buf[256];
++    QRectF rr = d->pageMatrix().mapRect(r);
++    //Note that the pdf spec sayes that we should add some sort of default appearence atleast for yes, which we dont ghost script provides one, however acroread does not
++    if (d->formFieldList == -1) d->formFieldList = d->requestObject();
++    d->xprintf("<<\n"
++               "/Type /Annot\n"
++               "/Parrent %d 0 R\n"
++               "/Rect[", d->formFieldList);
++    d->xprintf("%s ", qt_real_to_string(rr.left(),buf));
++    d->xprintf("%s ", qt_real_to_string(rr.top(),buf));
++    d->xprintf("%s ", qt_real_to_string(rr.right(),buf));
++    d->xprintf("%s", qt_real_to_string(rr.bottom(),buf));
++    d->xprintf("]\n"
++               "/FT/Btn\n"
++               "/Subtype/Widget\n"
++               "/P %d 0 R\n", d->pages.back());
++    if (checked)
++        d->xprintf("/AS /Yes\n");
++    if (!name.isEmpty()) {
++        d->xprintf("/T");
++        d->printString(name);
++        d->xprintf("\n");
++    }
++    d->xprintf("/Ff %d\n"
++               ">>\n"
++               "endobj\n",
++               (readOnly?1:0)<<0);
++    d->currentPage->annotations.push_back(obj);
++    d->formFields.push_back(obj);
++}
++
++void QPdfEngine::addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength)
++{
++    Q_D(QPdfEngine);
++    uint obj = d->addXrefEntry(-1);
++    char buf[256];
++    QRectF rr = d->pageMatrix().mapRect(r);
++    if (d->formFieldList == -1) d->formFieldList = d->requestObject();
++    d->xprintf("<<\n"
++               "/Type /Annot\n"
++               "/Parrent %d 0 R\n"
++               "/Rect[", d->formFieldList);
++    d->xprintf("%s ", qt_real_to_string(rr.left(),buf));
++    d->xprintf("%s ", qt_real_to_string(rr.top(),buf));
++    d->xprintf("%s ", qt_real_to_string(rr.right(),buf));
++    d->xprintf("%s", qt_real_to_string(rr.bottom(),buf));
++    d->xprintf("]\n"
++               "/BS<</S/I>>\n"
++               "/FT/Tx\n"
++               "/Subtype/Widget\n"
++               "/P %d 0 R\n", d->pages.back());
++    if (!text.isEmpty()) {
++        d->xprintf("/V");
++        d->printString(text);
++        d->xprintf("\n");
++    }
++    if (!name.isEmpty()) {
++        d->xprintf("/T");
++        d->printString(name);
++        d->xprintf("\n");
++    }
++    if (maxLength >= 0) 
++        d->xprintf("/MaxLen %d\n",maxLength);
++    d->xprintf("/DA(/Helv 12 Tf 0 g)\n"
++               "/Ff %d\n"
++               ">>\n"
++               "endobj\n",
++               (readOnly?1:0)<<0 | (password?1:0)<<13 | (multiLine?1:0)<<12
++        );
++    d->currentPage->annotations.push_back(obj);
++    d->formFields.push_back(obj);
++}
+ 
+-void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr)
++void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr, const QByteArray * data)
+ {
+     if (sr.isEmpty() || rectangle.isEmpty() || pixmap.isNull())
+         return;
+@@ -176,22 +323,35 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con
+ 
+     QRect sourceRect = sr.toRect();
+     QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap;
+-    QImage image = pm.toImage();
++    QImage unscaled = pm.toImage();
++    QImage image = unscaled;
++    
++    QRectF a = d->stroker.matrix.mapRect(rectangle);
++    QRectF c = d->paperRect();
++    int maxWidth = int(a.width() / c.width() * d->width() / 72.0 * d->imageDPI);
++    int maxHeight = int(a.height() / c.height() * d->height() / 72.0 * d->imageDPI);
++    if (image.width() > maxWidth || image.height() > maxHeight)
++        image = unscaled.scaled( image.size().boundedTo( QSize(maxWidth, maxHeight) ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
++    
++    bool useScaled=true;
+     bool bitmap = true;
+-    const int object = d->addImage(image, &bitmap, pm.cacheKey());
++    const int object = d->addImage(image, &bitmap, pm.cacheKey(), &unscaled, (sr == pixmap.rect()?data:0), &useScaled );
++    int width = useScaled?image.width():unscaled.width();
++    int height = useScaled?image.height():unscaled.height();
++
+     if (object < 0)
+         return;
+ 
+     *d->currentPage << "q\n/GSa gs\n";
+     *d->currentPage
+-        << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
++        << QPdf::generateMatrix(QTransform(rectangle.width() / width, 0, 0, rectangle.height() / height,
+                                            rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
+     if (bitmap) {
+         // set current pen as d->brush
+         d->brush = d->pen.brush();
+     }
+     setBrush();
+-    d->currentPage->streamImage(image.width(), image.height(), object);
++    d->currentPage->streamImage(width, height, object);
+     *d->currentPage << "Q\n";
+ 
+     d->brush = b;
+@@ -301,18 +461,68 @@ QPdfEnginePrivate::QPdfEnginePrivate(QPrinter::PrinterMode m)
+     : QPdfBaseEnginePrivate(m)
+ {
+     streampos = 0;
+-
++    doCompress = true;
++    imageDPI = 1400;
++    imageQuality = 94;
+     stream = new QDataStream;
+     pageOrder = QPrinter::FirstPageFirst;
+     orientation = QPrinter::Portrait;
++    outlineRoot = NULL;
++    outlineCurrent = NULL;
+     fullPage = false;
+ }
+ 
+ QPdfEnginePrivate::~QPdfEnginePrivate()
+ {
++    if (outlineRoot)
++      delete outlineRoot;
+     delete stream;
+ }
+ 
++void QPdfEnginePrivate::printAnchor(const QString &name) {
++    QByteArray a = name.toUtf8();
++    if (a.size() >= 127)
++        a = QCryptographicHash::hash(a,QCryptographicHash::Sha1);
++    xprintf("/");
++    for (int i=0; i < a.size(); ++i) {
++        unsigned char c = a[i];
++        if (('a' <= c && c <= 'z') ||
++            ('A' <= c && c <= 'Z') ||
++            ('0' <= c && c <= '9') ||
++            c == '.' || c == '_') 
++            xprintf("%c", c);
++        else if(c == 0)
++            xprintf("!");
++        else
++            xprintf("#%02x", c);
++    }
++}
++
++void QPdfEnginePrivate::writeOutlineChildren(OutlineItem * node) {
++    for (OutlineItem * i = node->firstChild; i != NULL; i = i->next)
++       i->obj = requestObject();
++    for (OutlineItem * i = node->firstChild; i != NULL; i = i->next) {
++       QPdfEnginePrivate::writeOutlineChildren(i);
++       addXrefEntry(i->obj);
++       xprintf("<</Title ");
++       printString(i->text);
++       xprintf("\n"
++               "  /Parent %d 0 R\n"
++               "  /Dest ", i->parent->obj);
++       printAnchor(i->anchor);
++       xprintf("\n  /Count 0\n");
++       if (i->next)
++           xprintf("  /Next %d 0 R\n", i->next->obj);
++       if (i->prev)
++           xprintf("  /Prev %d 0 R\n", i->prev->obj);
++       if (i->firstChild)
++           xprintf("  /First %d 0 R\n", i->firstChild->obj);
++       if (i->lastChild)
++           xprintf("  /Last %d 0 R\n", i->lastChild->obj);
++       xprintf(">>\n"
++               "endobj\n");
++    }
++}
+ 
+ #ifdef USE_NATIVE_GRADIENTS
+ int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject)
+@@ -520,10 +730,112 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
+     return patternObj;
+ }
+ 
++
++void QPdfEnginePrivate::convertImage(const QImage & image, QByteArray & imageData) {
++    int w = image.width();
++    int h = image.height();
++    imageData.resize(colorMode == QPrinter::GrayScale ? w * h : 3 * w * h);
++    uchar *data = (uchar *)imageData.data();
++    for (int y = 0; y < h; ++y) {
++        const QRgb *rgb = (const QRgb *)image.scanLine(y);
++        if (colorMode == QPrinter::GrayScale) {
++            for (int x = 0; x < w; ++x) {
++                *(data++) = qGray(*rgb);
++                ++rgb;
++            }
++        } else {
++            for (int x = 0; x < w; ++x) {
++                *(data++) = qRed(*rgb);
++                *(data++) = qGreen(*rgb);
++                *(data++) = qBlue(*rgb);
++                ++rgb;
++            }
++        }
++    }
++}
++
++#include <iostream>
++
++class jpg_header_reader {
++private:
++  const QByteArray * data;
++  int index;
++  
++  class jpeg_exception {};
++  
++  unsigned char next() {
++    if (index == data->size()) throw jpeg_exception();
++    return data->data()[index++];
++  }
++    
++  void skip() {
++    int l = (next() << 8) + next();
++    if (l < 2) throw jpeg_exception();
++    for (int i=2; i < l; ++i) next();
++  }
++
++  void read_header() {
++    int l = (next() << 8) + next();
++    if (l < 2) throw jpeg_exception();
++    precision = next();
++    height = (next() << 8) + next();
++    width = (next() << 8) + next();
++    components = next();
++    if (l != 8 + components*3) throw jpeg_exception();
++  }
++  
++public:
++  bool read(const QByteArray * d) {
++    index=0;
++    data=d;
++    try {
++      if (next() != 0xFF) throw jpeg_exception();
++      unsigned char marker = next();
++      if (marker != 0xD8) throw jpeg_exception();
++      while (true) {
++	marker = next();
++	while (marker != 0xFF) marker=next();
++	while (marker == 0xFF) marker=next();
++	switch(marker) {
++	case 0xC0:
++	case 0xC1:
++	case 0xC2:
++	case 0xC3:
++	case 0xC5:
++	case 0xC6:
++	case 0xC7:
++	case 0xC9:
++	case 0xCA:
++	case 0xCB:
++	case 0xCD:
++	case 0xCE:
++	case 0xCF:
++	  read_header();
++	  return true;
++	case 0xDA:
++	case 0xD9:
++	  return false;
++	default:
++	  skip();
++	  break;
++	}
++      }
++    } catch(jpeg_exception) {
++      return false;
++    }
++    return true;
++  }
++
++  int precision, height, width, components;
++    
++};
++
++
++
+ /*!
+  * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
+  */
+-int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no)
++int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no, const QImage * noneScaled, const QByteArray * data, bool * useScaled)
+ {
+     if (img.isNull())
+         return -1;
+@@ -564,65 +876,97 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
+         }
+         object = writeImage(data, w, h, d, 0, 0);
+     } else {
+-        QByteArray softMaskData;
+-        bool dct = false;
+         QByteArray imageData;
+-        bool hasAlpha = false;
+-        bool hasMask = false;
+-
++        uLongf target=1024*1024*1024;
++        bool uns=false;
++        bool dct = false;
++        
++        d = (colorMode == QPrinter::GrayScale) ? 8 : 32;
++        	
+         if (QImageWriter::supportedImageFormats().contains("jpeg") && colorMode != QPrinter::GrayScale) {
+-            QBuffer buffer(&imageData);
++            QByteArray imageData2;
++            
++            QBuffer buffer(&imageData2);
+             QImageWriter writer(&buffer, "jpeg");
+-            writer.setQuality(94);
++            writer.setQuality(imageQuality);
+             writer.write(image);
+-            dct = true;
+-
+-            if (format != QImage::Format_RGB32) {
+-                softMaskData.resize(w * h);
+-                uchar *sdata = (uchar *)softMaskData.data();
+-                for (int y = 0; y < h; ++y) {
+-                    const QRgb *rgb = (const QRgb *)image.scanLine(y);
+-                    for (int x = 0; x < w; ++x) {
+-                        uchar alpha = qAlpha(*rgb);
+-                        *sdata++ = alpha;
+-                        hasMask |= (alpha < 255);
+-                        hasAlpha |= (alpha != 0 && alpha != 255);
+-                        ++rgb;
+-                    }
+-                }
++            
++            if ((uLongf)imageData2.size() < target) {
++                imageData=imageData2;
++                target = imageData2.size();
++                dct = true;
++                uns=false;
+             }
+-        } else {
+-            imageData.resize(colorMode == QPrinter::GrayScale ? w * h : 3 * w * h);
+-            uchar *data = (uchar *)imageData.data();
++        }
++
++        if (noneScaled && noneScaled->rect() != image.rect()) {
++            QByteArray imageData2;
++            convertImage(*noneScaled, imageData2);
++            uLongf len = imageData2.size();
++            uLongf destLen = len + len/100 + 13; // zlib requirement
++            Bytef* dest = new Bytef[destLen];
++            if (Z_OK == ::compress(dest, &destLen, (const Bytef*) imageData2.data(), (uLongf)len) &&
++                (uLongf)destLen < target) {
++                imageData=imageData2;
++                target=destLen;
++                dct=false;
++                uns=true;
++            }
++            delete[] dest;
++        }
++        
++        {
++            QByteArray imageData2;
++            convertImage(image, imageData2);
++            uLongf len = imageData2.size();
++            uLongf destLen = len + len/100 + 13; // zlib requirement
++            Bytef* dest = new Bytef[destLen];
++            if (Z_OK == ::compress(dest, &destLen, (const Bytef*) imageData2.data(), (uLongf)len) &&
++                (uLongf)destLen < target) {
++                imageData=imageData2;
++                target=destLen;
++                dct=false;
++                uns=false;
++            }
++            delete[] dest;
++        }
++
++
++        if (colorMode != QPrinter::GrayScale && noneScaled != 0 && data != 0) {
++	  jpg_header_reader header;
++	  if (header.read(data)) {
++	    d = header.components == 3?32:8;
++            imageData = *data;
++            target=data->size();
++            dct=true;
++            uns=true;
++	  }
++        }
++
++        if (uns) {
++            w = noneScaled->width();
++            h = noneScaled->height();
++        }
++        if (useScaled) *useScaled = (uns?false:true);
++        QByteArray softMaskData;
++        bool hasAlpha = false;
++        bool hasMask = false;
++        
++        if (format != QImage::Format_RGB32) {
+             softMaskData.resize(w * h);
+             uchar *sdata = (uchar *)softMaskData.data();
+             for (int y = 0; y < h; ++y) {
+-                const QRgb *rgb = (const QRgb *)image.scanLine(y);
+-                if (colorMode == QPrinter::GrayScale) {
+-                    for (int x = 0; x < w; ++x) {
+-                        *(data++) = qGray(*rgb);
+-                        uchar alpha = qAlpha(*rgb);
+-                        *sdata++ = alpha;
+-                        hasMask |= (alpha < 255);
+-                        hasAlpha |= (alpha != 0 && alpha != 255);
+-                        ++rgb;
+-                    }
+-                } else {
+-                    for (int x = 0; x < w; ++x) {
+-                        *(data++) = qRed(*rgb);
+-                        *(data++) = qGreen(*rgb);
+-                        *(data++) = qBlue(*rgb);
+-                        uchar alpha = qAlpha(*rgb);
+-                        *sdata++ = alpha;
+-                        hasMask |= (alpha < 255);
+-                        hasAlpha |= (alpha != 0 && alpha != 255);
+-                        ++rgb;
+-                    }
++                const QRgb *rgb = (const QRgb *)(uns?noneScaled->scanLine(y):image.scanLine(y));
++                for (int x = 0; x < w; ++x) {
++                    uchar alpha = qAlpha(*rgb);
++                    *sdata++ = alpha;
++                    hasMask |= (alpha < 255);
++                    hasAlpha |= (alpha != 0 && alpha != 255);
++                    ++rgb;
+                 }
+             }
+-            if (format == QImage::Format_RGB32)
+-                hasAlpha = hasMask = false;
+         }
++        
+         int maskObject = 0;
+         int softMaskObject = 0;
+         if (hasAlpha) {
+@@ -644,7 +988,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
+             }
+             maskObject = writeImage(mask, w, h, 1, 0, 0);
+         }
+-        object = writeImage(imageData, w, h, colorMode == QPrinter::GrayScale ? 8 : 32,
++        object = writeImage(imageData, w, h, d,
+                             maskObject, softMaskObject, dct);
+     }
+     imageCache.insert(serial_no, object);
+@@ -754,7 +1098,7 @@ void QPdfEnginePrivate::xprintf(const char* fmt, ...)
+ int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
+ {
+ #ifndef QT_NO_COMPRESS
+-    if (do_compress) {
++    if (doCompress) {
+         int size = QPdfPage::chunkSize();
+         int sum = 0;
+         ::z_stream zStruct;
+@@ -828,7 +1172,7 @@ int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
+ int QPdfEnginePrivate::writeCompressed(const char *src, int len)
+ {
+ #ifndef QT_NO_COMPRESS
+-    if(do_compress) {
++    if(doCompress) {
+         uLongf destLen = len + len/100 + 13; // zlib requirement
+         Bytef* dest = new Bytef[destLen];
+         if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) {
+@@ -881,7 +1225,7 @@ int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height,
+         write(data);
+         len = data.length();
+     } else {
+-        if (do_compress)
++        if (doCompress)
+             xprintf("/Filter /FlateDecode\n>>\nstream\n");
+         else
+             xprintf(">>\nstream\n");
+@@ -904,14 +1248,9 @@ void QPdfEnginePrivate::writeHeader()
+ 
+     writeInfo();
+ 
+-    catalog = addXrefEntry(-1);
+     pageRoot = requestObject();
+-    xprintf("<<\n"
+-            "/Type /Catalog\n"
+-            "/Pages %d 0 R\n"
+-            ">>\n"
+-            "endobj\n", pageRoot);
+-
++    
++    formFieldList = -1;
+     // graphics state
+     graphicsState = addXrefEntry(-1);
+     xprintf("<<\n"
+@@ -939,17 +1278,26 @@ void QPdfEnginePrivate::writeInfo()
+     xprintf("\n/Creator ");
+     printString(creator);
+     xprintf("\n/Producer ");
+-    printString(QString::fromLatin1("Qt " QT_VERSION_STR " (C) 2011 Nokia Corporation and/or its subsidiary(-ies)"));
+-    QDateTime now = QDateTime::currentDateTime().toUTC();
++    printString(QString::fromLatin1("wkhtmltopdf"));
++    QDateTime now = QDateTime::currentDateTime();
+     QTime t = now.time();
+     QDate d = now.date();
+-    xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n",
++    xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d",
+             d.year(),
+             d.month(),
+             d.day(),
+             t.hour(),
+             t.minute(),
+             t.second());
++    QDateTime fake=now;
++    fake.setTimeSpec(Qt::UTC);
++    int offset = now.secsTo(fake);
++    if (offset == 0)
++        xprintf("Z)\n");
++    else if (offset < 0)
++        xprintf("-%02d'%02d')\n", (-offset)/60/60 , ((-offset)/60) % 60);
++    else if (offset > 0)
++        xprintf("+%02d'%02d')\n", offset/60/60 , (offset/60) % 60);
+     xprintf(">>\n"
+             "endobj\n");
+ }
+@@ -1035,7 +1383,7 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
+         s << "<<\n"
+             "/Length1 " << fontData.size() << "\n"
+             "/Length " << length_object << "0 R\n";
+-        if (do_compress)
++        if (doCompress)
+             s << "/Filter /FlateDecode\n";
+         s << ">>\n"
+             "stream\n";
+@@ -1097,6 +1445,101 @@ void QPdfEnginePrivate::writeFonts()
+     fonts.clear();
+ }
+ 
++
++void QPdfEngine::addHyperlink(const QRectF &r, const QUrl &url)
++{
++    Q_D(QPdfEngine);
++    char buf[256];
++    QRectF rr = d->pageMatrix().mapRect(r);
++    uint annot = d->addXrefEntry(-1);
++    QByteArray urlascii = url.toString().toLatin1();
++    int len = urlascii.size();
++    char *url_esc = new char[len * 2 + 1];
++    const char * urldata = urlascii.constData();
++    int k = 0;
++    for (int j = 0; j < len; j++, k++){
++        if (urldata[j] == '(' ||
++            urldata[j] == ')' ||
++            urldata[j] == '\\'){
++            url_esc[k] = '\\';
++            k++;
++        }
++        url_esc[k] = urldata[j];
++    }
++    url_esc[k] = 0;
++    d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [");
++    d->xprintf("%s ", qt_real_to_string(rr.left(),buf));
++    d->xprintf("%s ", qt_real_to_string(rr.top(),buf));
++    d->xprintf("%s ", qt_real_to_string(rr.right(),buf));
++    d->xprintf("%s", qt_real_to_string(rr.bottom(),buf));
++    d->xprintf("]\n/Border [0 0 0]\n/A <<\n");
++    d->xprintf("/Type /Action\n/S /URI\n/URI (%s)\n", url_esc);
++    d->xprintf(">>\n>>\n");
++    d->xprintf("endobj\n");
++    d->currentPage->annotations.append(annot);
++    delete[] url_esc;
++}
++
++void QPdfEngine::addLink(const QRectF &r, const QString &anchor)
++{
++    Q_D(QPdfEngine);
++    char buf[256];
++    QRectF rr = d->pageMatrix().mapRect(r);
++    uint annot = d->addXrefEntry(-1);
++    d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [");
++    d->xprintf("%s ", qt_real_to_string(rr.left(),buf));
++    d->xprintf("%s ", qt_real_to_string(rr.top(),buf));
++    d->xprintf("%s ", qt_real_to_string(rr.right(),buf));
++    d->xprintf("%s", qt_real_to_string(rr.bottom(),buf));
++    d->xprintf("]\n/Border [0 0 0]\n/Dest ");
++    d->printAnchor(anchor);
++    d->xprintf("\n>>\n");
++    d->xprintf("endobj\n");
++    d->currentPage->annotations.append(annot);
++}
++
++void QPdfEngine::addAnchor(const QRectF &r, const QString &name)
++{
++    Q_D(QPdfEngine);
++    char buf[256];
++    QRectF rr = d->pageMatrix().mapRect(r);
++    uint anchor = d->addXrefEntry(-1);
++    d->xprintf("[%d /XYZ %s \n",
++               d->pages.size() - 1,
++               qt_real_to_string(rr.left(), buf));
++    d->xprintf("%s 0]\n",
++               qt_real_to_string(rr.bottom(), buf));
++    d->xprintf("endobj\n");
++    d->anchors[name] = anchor;
++}
++
++void QPdfEngine::beginSectionOutline(const QString &text, const QString &anchor)
++{
++    Q_D(QPdfEngine);
++    if (d->outlineCurrent == NULL) {
++        if (d->outlineRoot)
++            delete d->outlineRoot;
++        d->outlineCurrent = d->outlineRoot = new QPdfEnginePrivate::OutlineItem(QString(), QString());
++    }
++    
++    QPdfEnginePrivate::OutlineItem *i = new QPdfEnginePrivate::OutlineItem(text, anchor);
++    i->parent = d->outlineCurrent;
++    i->prev = d->outlineCurrent->lastChild;
++    if (d->outlineCurrent->firstChild)
++        d->outlineCurrent->lastChild->next = i;
++    else
++        d->outlineCurrent->firstChild = i;
++    d->outlineCurrent->lastChild = i;
++    d->outlineCurrent = i;
++}
++
++void QPdfEngine::endSectionOutline()
++{
++    Q_D(QPdfEngine);
++    if (d->outlineCurrent)
++        d->outlineCurrent = d->outlineCurrent->parent;
++}
++
+ void QPdfEnginePrivate::writePage()
+ {
+     if (pages.empty())
+@@ -1167,7 +1610,7 @@ void QPdfEnginePrivate::writePage()
+     addXrefEntry(pageStream);
+     xprintf("<<\n"
+             "/Length %d 0 R\n", pageStreamLength); // object number for stream length object
+-    if (do_compress)
++    if (doCompress)
+         xprintf("/Filter /FlateDecode\n");
+ 
+     xprintf(">>\n");
+diff --git a/src/gui/painting/qprintengine_pdf_p.h b/src/gui/painting/qprintengine_pdf_p.h
+index 9b9185a..1586caa 100644
+--- a/src/gui/painting/qprintengine_pdf_p.h
++++ b/src/gui/painting/qprintengine_pdf_p.h
+@@ -92,7 +92,12 @@ public:
+     // reimplementations QPaintEngine
+     bool begin(QPaintDevice *pdev);
+     bool end();
+-    void drawPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr);
++
++    void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data=0);
++    void drawPixmap(const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr) {
++        drawPixmap(rectangle, pixmap, sr, 0);
++    }
++
+     void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
+                    Qt::ImageConversionFlags flags = Qt::AutoColor);
+     void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point);
+@@ -108,12 +113,23 @@ public:
+ 
+     void setBrush();
+ 
++    virtual void addHyperlink(const QRectF &r, const QUrl &url);
++    virtual void addAnchor(const QRectF &r, const QString &name);
++    virtual void addLink(const QRectF &r, const QString &anchor);
++    virtual void addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength);
++    virtual void addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly);
++
+     // ### unused, should have something for this in QPrintEngine
+     void setAuthor(const QString &author);
+     QString author() const;
+ 
+     void setDevice(QIODevice* dev);
+ 
++    void beginSectionOutline(const QString &text, const QString &anchor);
++    void endSectionOutline();
++
++    void setProperty(PrintEnginePropertyKey key, const QVariant &value);
++    QVariant property(PrintEnginePropertyKey key) const;
+ private:
+     Q_DISABLE_COPY(QPdfEngine)
+ 
+@@ -124,6 +140,35 @@ class QPdfEnginePrivate : public QPdfBaseEnginePrivate
+ {
+     Q_DECLARE_PUBLIC(QPdfEngine)
+ public:
++  
++    class OutlineItem {
++    public:
++        OutlineItem *parent;
++        OutlineItem *next;
++        OutlineItem *prev;
++        OutlineItem *firstChild;
++        OutlineItem *lastChild;
++        uint obj;
++        QString text;
++        QString anchor;
++        
++        OutlineItem(const QString &t, const QString &a): 
++            parent(NULL), next(NULL), prev(NULL), firstChild(NULL), lastChild(NULL),
++            obj(0), text(t), anchor(a) {}
++        ~OutlineItem() {
++            OutlineItem *i = firstChild;
++            while(i != NULL) { 
++                OutlineItem *n = i->next;
++                delete i;
++                i=n;
++            }
++        }
++    };
++    
++    OutlineItem *outlineRoot;
++    OutlineItem *outlineCurrent;
++    void writeOutlineChildren(OutlineItem *node);
++    
+     QPdfEnginePrivate(QPrinter::PrinterMode m);
+     ~QPdfEnginePrivate();
+ 
+@@ -141,7 +186,9 @@ public:
+     void writeHeader();
+     void writeTail();
+ 
+-    int addImage(const QImage &image, bool *bitmap, qint64 serial_no);
++    void convertImage(const QImage & image, QByteArray & imageData);
++
++    int addImage(const QImage &image, bool *bitmap, qint64 serial_no, const QImage * noneScaled=0, const QByteArray * data=0, bool * useScaled=0);
+     int addConstantAlphaObject(int brushAlpha, int penAlpha = 255);
+     int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject);
+ 
+@@ -161,16 +208,25 @@ private:
+     void writeFonts();
+     void embedFont(QFontSubset *font);
+ 
++    int formFieldList;
++    QVector<uint> formFields;
+     QVector<int> xrefPositions;
+     QDataStream* stream;
+     int streampos;
+ 
++    bool doCompress;
++    int imageDPI;
++    int imageQuality;
++
+     int writeImage(const QByteArray &data, int width, int height, int depth,
+                    int maskObject, int softMaskObject, bool dct = false);
+     void writePage();
+ 
+     int addXrefEntry(int object, bool printostr = true);
++
+     void printString(const QString &string);
++    void printAnchor(const QString &name);
++    
+     void xprintf(const char* fmt, ...);
+     inline void write(const QByteArray &data) {
+         stream->writeRawData(data.constData(), data.size());
+@@ -183,6 +239,8 @@ private:
+ 
+     // various PDF objects
+     int pageRoot, catalog, info, graphicsState, patternColorSpace;
++    QVector<uint> dests;
++    QHash<QString, uint> anchors;
+     QVector<uint> pages;
+     QHash<qint64, uint> imageCache;
+     QHash<QPair<uint, uint>, uint > alphaCache;
+diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
+index 134447c..2c58619 100644
+--- a/src/gui/painting/qprinter.cpp
++++ b/src/gui/painting/qprinter.cpp
+@@ -933,6 +933,39 @@ void QPrinter::setOutputFileName(const QString &fileName)
+     d->addToManualSetList(QPrintEngine::PPK_OutputFileName);
+ }
+ 
++/*!
++    Add a section to the document outline. All following sections will be added
++    to as subsections to this section, until endSectionOutline() has been called.
++
++    \a name is the name of the added section. \a anchor is the name of an anchor
++    indicating the beginning of the section.  This anchor must be added by calling
++    QPainter::addAnchor().
++
++    Note that for output formats not supporting outlines, currently all other then PDF,
++    this call has no effect.
++
++    \sa endSectionOutline() QPainter::addAnchor() 
++
++    \since 4.7
++*/
++void QPrinter::beginSectionOutline(const QString &name, const QString &anchor)
++{
++    Q_D(QPrinter);
++    d->printEngine->beginSectionOutline(name, anchor);
++}
++
++/*!
++    End the current section.
++
++    \sa beginSectionOutline()
++
++    \since 4.7
++*/
++void QPrinter::endSectionOutline() 
++{
++    Q_D(QPrinter);
++    d->printEngine->endSectionOutline();
++}
+ 
+ /*!
+   Returns the name of the program that sends the print output to the
+diff --git a/src/gui/painting/qprinter.h b/src/gui/painting/qprinter.h
+index f133a5d..46baf8c 100644
+--- a/src/gui/painting/qprinter.h
++++ b/src/gui/painting/qprinter.h
+@@ -147,6 +147,9 @@ public:
+     enum PrinterOption { PrintToFile, PrintSelection, PrintPageRange };
+ #endif // QT3_SUPPORT
+ 
++    void beginSectionOutline(const QString &text, const QString &anchor);
++    void endSectionOutline();
++
+     void setOutputFormat(OutputFormat format);
+     OutputFormat outputFormat() const;
+ 
+diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
+index 52ce9a7..eddbb80 100644
+--- a/src/gui/styles/qstyle.cpp
++++ b/src/gui/styles/qstyle.cpp
+@@ -47,6 +47,7 @@
+ #include "qpixmapcache.h"
+ #include "qstyleoption.h"
+ #include "private/qstyle_p.h"
++#include "private/qapplication_p.h"
+ #ifndef QT_NO_DEBUG
+ #include "qdebug.h"
+ #endif
+@@ -2229,7 +2230,7 @@ QPalette QStyle::standardPalette() const
+ {
+ #ifdef Q_WS_X11
+     QColor background;
+-    if (QX11Info::appDepth() > 8)
++    if (!qt_is_gui_used || QX11Info::appDepth() > 8)
+         background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey
+     else
+         background = QColor(192, 192, 192);
+diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp
+index f512992..9ee9096 100644
+--- a/src/svg/qsvggenerator.cpp
++++ b/src/svg/qsvggenerator.cpp
+@@ -103,6 +103,7 @@ public:
+ 
+         afterFirstUpdate = false;
+         numGradients = 0;
++        clip = false;
+     }
+ 
+     QSize size;
+@@ -129,6 +130,9 @@ public:
+ 
+     QString currentGradientName;
+     int numGradients;
++    QString stateString;
++    QString oldStateString;
++    bool clip;
+ 
+     struct _attributes {
+         QString document_title;
+@@ -141,6 +145,18 @@ public:
+         QString dashPattern, dashOffset;
+         QString fill, fillOpacity;
+     } attributes;
++
++    void emitState() {
++        if (stateString == oldStateString) return;
++
++        // close old state and start a new one...
++        if (afterFirstUpdate)
++            *stream << "</g>\n\n";
++        
++        *stream << stateString;
++        afterFirstUpdate = true;
++        oldStateString = stateString;
++    }
+ };
+ 
+ static inline QPaintEngine::PaintEngineFeatures svgEngineFeatures()
+@@ -322,7 +338,7 @@ public:
+     }
+ 
+ 
+-    void qpenToSvg(const QPen &spen)
++    void qpenToSvg(const QPen &spen, QTextStream & s)
+     {
+         QString width;
+ 
+@@ -330,7 +346,7 @@ public:
+ 
+         switch (spen.style()) {
+         case Qt::NoPen:
+-            stream() << QLatin1String("stroke=\"none\" ");
++            s << QLatin1String("stroke=\"none\" ");
+ 
+             d_func()->attributes.stroke = QLatin1String("none");
+             d_func()->attributes.strokeOpacity = QString();
+@@ -344,8 +360,8 @@ public:
+             d_func()->attributes.stroke = color;
+             d_func()->attributes.strokeOpacity = colorOpacity;
+ 
+-            stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
+-            stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
++            s << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
++            s << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
+         }
+             break;
+         case Qt::DashLine:
+@@ -368,10 +384,10 @@ public:
+             d_func()->attributes.dashPattern = dashPattern;
+             d_func()->attributes.dashOffset = dashOffset;
+ 
+-            stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
+-            stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
+-            stream() << QLatin1String("stroke-dasharray=\"")<<dashPattern<< QLatin1String("\" ");
+-            stream() << QLatin1String("stroke-dashoffset=\"")<<dashOffset<< QLatin1String("\" ");
++            s << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
++            s << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
++            s << QLatin1String("stroke-dasharray=\"")<<dashPattern<< QLatin1String("\" ");
++            s << QLatin1String("stroke-dashoffset=\"")<<dashOffset<< QLatin1String("\" ");
+             break;
+         }
+         default:
+@@ -380,50 +396,50 @@ public:
+         }
+ 
+         if (spen.widthF() == 0)
+-            stream() <<"stroke-width=\"1\" ";
++            s <<"stroke-width=\"1\" ";
+         else
+-            stream() <<"stroke-width=\"" << spen.widthF() << "\" ";
++            s <<"stroke-width=\"" << spen.widthF() << "\" ";
+ 
+         switch (spen.capStyle()) {
+         case Qt::FlatCap:
+-            stream() << "stroke-linecap=\"butt\" ";
++            s << "stroke-linecap=\"butt\" ";
+             break;
+         case Qt::SquareCap:
+-            stream() << "stroke-linecap=\"square\" ";
++            s << "stroke-linecap=\"square\" ";
+             break;
+         case Qt::RoundCap:
+-            stream() << "stroke-linecap=\"round\" ";
++            s << "stroke-linecap=\"round\" ";
+             break;
+         default:
+             qWarning("Unhandled cap style");
+         }
+         switch (spen.joinStyle()) {
+         case Qt::MiterJoin:
+-            stream() << "stroke-linejoin=\"miter\" "
++            s << "stroke-linejoin=\"miter\" "
+                         "stroke-miterlimit=\""<<spen.miterLimit()<<"\" ";
+             break;
+         case Qt::BevelJoin:
+-            stream() << "stroke-linejoin=\"bevel\" ";
++            s << "stroke-linejoin=\"bevel\" ";
+             break;
+         case Qt::RoundJoin:
+-            stream() << "stroke-linejoin=\"round\" ";
++            s << "stroke-linejoin=\"round\" ";
+             break;
+         case Qt::SvgMiterJoin:
+-            stream() << "stroke-linejoin=\"miter\" "
++            s << "stroke-linejoin=\"miter\" "
+                         "stroke-miterlimit=\""<<spen.miterLimit()<<"\" ";
+             break;
+         default:
+             qWarning("Unhandled join style");
+         }
+     }
+-    void qbrushToSvg(const QBrush &sbrush)
++    void qbrushToSvg(const QBrush &sbrush, QTextStream & s)
+     {
+         d_func()->brush = sbrush;
+         switch (sbrush.style()) {
+         case Qt::SolidPattern: {
+             QString color, colorOpacity;
+             translate_color(sbrush.color(), &color, &colorOpacity);
+-            stream() << "fill=\"" << color << "\" "
++            s << "fill=\"" << color << "\" "
+                         "fill-opacity=\""
+                      << colorOpacity << "\" ";
+             d_func()->attributes.fill = color;
+@@ -434,22 +450,22 @@ public:
+             saveLinearGradientBrush(sbrush.gradient());
+             d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);
+             d_func()->attributes.fillOpacity = QString();
+-            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
++            s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
+             break;
+         case Qt::RadialGradientPattern:
+             saveRadialGradientBrush(sbrush.gradient());
+             d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);
+             d_func()->attributes.fillOpacity = QString();
+-            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
++            s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
+             break;
+         case Qt::ConicalGradientPattern:
+             saveConicalGradientBrush(sbrush.gradient());
+             d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);
+             d_func()->attributes.fillOpacity = QString();
+-            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
++            s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
+             break;
+         case Qt::NoBrush:
+-            stream() << QLatin1String("fill=\"none\" ");
++            s << QLatin1String("fill=\"none\" ");
+             d_func()->attributes.fill = QLatin1String("none");
+             d_func()->attributes.fillOpacity = QString();
+             return;
+@@ -458,7 +474,7 @@ public:
+            break;
+         }
+     }
+-    void qfontToSvg(const QFont &sfont)
++    void qfontToSvg(const QFont &sfont, QTextStream & s)
+     {
+         Q_D(QSvgPaintEngine);
+ 
+@@ -488,12 +504,23 @@ public:
+         d->attributes.font_family = d->font.family();
+         d->attributes.font_style = d->font.italic() ? QLatin1String("italic") : QLatin1String("normal");
+ 
+-        *d->stream << "font-family=\"" << d->attributes.font_family << "\" "
+-                      "font-size=\"" << d->attributes.font_size << "\" "
+-                      "font-weight=\"" << d->attributes.font_weight << "\" "
+-                      "font-style=\"" << d->attributes.font_style << "\" "
+-                   << endl;
++        s << "font-family=\"" << d->attributes.font_family << "\" "
++             "font-size=\"" << d->attributes.font_size << "\" "
++             "font-weight=\"" << d->attributes.font_weight << "\" "
++             "font-style=\"" << d->attributes.font_style << "\" "
++             << endl;
++    }
++
++    void setViewBoxClip(bool clip) {
++        Q_D(QSvgPaintEngine);
++        d->clip = clip;
+     }
++    
++    bool viewBoxClip() const {
++        Q_D(const QSvgPaintEngine);
++        return d->clip;
++    }
++
+ };
+ 
+ class QSvgGeneratorPrivate
+@@ -808,6 +835,27 @@ int QSvgGenerator::metric(QPaintDevice::PaintDeviceMetric metric) const
+     return 0;
+ }
+ 
++/*!
++    \property QSvgGenerator::resolution
++    \brief do not draw objects outside the viewBox
++    \since 4.7
++
++    When specified objects drawn compleatly outsite the viewBox
++    are not include in the output SVG.
++
++    \sa viewBox
++*/
++
++bool QSvgGenerator::viewBoxClip() const {
++    Q_D(const QSvgGenerator);
++    return d->engine->viewBoxClip();
++}
++
++void QSvgGenerator::setViewBoxClip(bool clip) {
++    Q_D(QSvgGenerator);
++    d->engine->setViewBoxClip(clip);
++}
++
+ /*****************************************************************************
+  * class QSvgPaintEngine
+  */
+@@ -908,10 +956,13 @@ void QSvgPaintEngine::drawImage(const QRectF &r, const QImage &image,
+                                 const QRectF &sr,
+                                 Qt::ImageConversionFlag flags)
+ {
+-    //Q_D(QSvgPaintEngine);
++    Q_D(QSvgPaintEngine);
+ 
+     Q_UNUSED(sr);
+     Q_UNUSED(flags);
++    if (d->clip && !d->matrix.mapRect(r).intersects(d->viewBox)) return;
++    d->emitState();
++
+     stream() << "<image ";
+     stream() << "x=\""<<r.x()<<"\" "
+                 "y=\""<<r.y()<<"\" "
+@@ -932,53 +983,35 @@ void QSvgPaintEngine::drawImage(const QRectF &r, const QImage &image,
+ void QSvgPaintEngine::updateState(const QPaintEngineState &state)
+ {
+     Q_D(QSvgPaintEngine);
+-    QPaintEngine::DirtyFlags flags = state.state();
+-
+-    // always stream full gstate, which is not required, but...
+-    flags |= QPaintEngine::AllDirty;
+-
+-    // close old state and start a new one...
+-    if (d->afterFirstUpdate)
+-        *d->stream << "</g>\n\n";
+-
+-    *d->stream << "<g ";
+ 
+-    if (flags & QPaintEngine::DirtyBrush) {
+-        qbrushToSvg(state.brush());
+-    }
+-
+-    if (flags & QPaintEngine::DirtyPen) {
+-        qpenToSvg(state.pen());
+-    }
+-
+-    if (flags & QPaintEngine::DirtyTransform) {
+-        d->matrix = state.matrix();
+-        *d->stream << "transform=\"matrix(" << d->matrix.m11() << ','
+-                   << d->matrix.m12() << ','
+-                   << d->matrix.m21() << ',' << d->matrix.m22() << ','
+-                   << d->matrix.dx() << ',' << d->matrix.dy()
+-                   << ")\""
+-                   << endl;
+-    }
+-
+-    if (flags & QPaintEngine::DirtyFont) {
+-        qfontToSvg(state.font());
+-    }
+-
+-    if (flags & QPaintEngine::DirtyOpacity) {
+-        if (!qFuzzyIsNull(state.opacity() - 1))
+-            stream() << "opacity=\""<<state.opacity()<<"\" ";
+-    }
+-
+-    *d->stream << '>' << endl;
+-
+-    d->afterFirstUpdate = true;
++    d->stateString="";
++    QTextStream stateStream(&d->stateString);
++    stateStream << "<g ";
++    qbrushToSvg(state.brush(), stateStream);
++    qpenToSvg(state.pen(), stateStream);
++    
++    d->matrix = state.matrix();
++    stateStream << "transform=\"matrix(" << d->matrix.m11() << ','
++                << d->matrix.m12() << ','
++                << d->matrix.m21() << ',' << d->matrix.m22() << ','
++                << d->matrix.dx() << ',' << d->matrix.dy()
++                << ")\""
++                << endl;
++    qfontToSvg(state.font(), stateStream);
++    
++    if (!qFuzzyIsNull(state.opacity() - 1))
++        stateStream << "opacity=\""<<state.opacity()<<"\" ";
++    
++    stateStream << '>' << endl;
+ }
+ 
+ void QSvgPaintEngine::drawPath(const QPainterPath &p)
+ {
+     Q_D(QSvgPaintEngine);
+ 
++    if (d->clip && !d->matrix.mapRect(p.boundingRect()).intersects(d->viewBox)) return;
++    d->emitState();
++    
+     *d->stream << "<path vector-effect=\""
+                << (state->pen().isCosmetic() ? "non-scaling-stroke" : "none")
+                << "\" fill-rule=\""
+@@ -1024,12 +1057,15 @@ void QSvgPaintEngine::drawPolygon(const QPointF *points, int pointCount,
+ {
+     Q_ASSERT(pointCount >= 2);
+ 
+-    //Q_D(QSvgPaintEngine);
++    Q_D(QSvgPaintEngine);
+ 
+     QPainterPath path(points[0]);
+     for (int i=1; i<pointCount; ++i)
+         path.lineTo(points[i]);
+ 
++    if (d->clip && !d->matrix.mapRect(path.boundingRect()).intersects(d->viewBox)) return;
++    d->emitState();
++
+     if (mode == PolylineMode) {
+         stream() << "<polyline fill=\"none\" vector-effect=\""
+                  << (state->pen().isCosmetic() ? "non-scaling-stroke" : "none")
+@@ -1051,6 +1087,12 @@ void QSvgPaintEngine::drawTextItem(const QPointF &pt, const QTextItem &textItem)
+     if (d->pen.style() == Qt::NoPen)
+         return;
+ 
++    if (d->clip) {
++        QRectF b=painter()->boundingRect( QRectF(pt, QSize()) , Qt::AlignLeft, textItem.text());
++        if (!d->matrix.mapRect(b).intersects(d->viewBox)) return;
++    }
++    d->emitState();
++
+     const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+     QString s = QString::fromRawData(ti.chars, ti.num_chars);
+ 
+@@ -1060,7 +1102,7 @@ void QSvgPaintEngine::drawTextItem(const QPointF &pt, const QTextItem &textItem)
+                   "stroke=\"none\" "
+                   "xml:space=\"preserve\" "
+                   "x=\"" << pt.x() << "\" y=\"" << pt.y() << "\" ";
+-    qfontToSvg(textItem.font());
++    qfontToSvg(textItem.font(), *d->stream);
+     *d->stream << " >"
+                << Qt::escape(s)
+                << "</text>"
+diff --git a/src/svg/qsvggenerator.h b/src/svg/qsvggenerator.h
+index 7981f28..2197ad8 100644
+--- a/src/svg/qsvggenerator.h
++++ b/src/svg/qsvggenerator.h
+@@ -96,6 +96,9 @@ public:
+ 
+     void setResolution(int dpi);
+     int resolution() const;
++
++    void setViewBoxClip(bool clip);
++    bool viewBoxClip() const;
+ protected:
+     QPaintEngine *paintEngine() const;
+     int metric(QPaintDevice::PaintDeviceMetric metric) const;
+diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
+index 4b8000d..6d52696 100644
+--- a/tools/configure/configureapp.cpp
++++ b/tools/configure/configureapp.cpp
+@@ -2381,9 +2381,9 @@ bool Configure::checkAvailability(const QString &part)
+         available = qmakeSpec == "win32-msvc2005" || qmakeSpec == "win32-msvc2008" ||
+                 qmakeSpec == "win32-msvc2010" || qmakeSpec == "win32-msvc2012" || qmakeSpec.startsWith("win32-g++");
+         if (dictionary[ "SHARED" ] == "no") {
+-            cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl
+-                 << endl;
+-            available = false;
++           // cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl
++           //      << endl;
++          //  available = false;
+         }
+     } else if (part == "AUDIO_BACKEND") {
+         available = true;
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/qt4.git/commitdiff/3583d8d70a3b67403433a8664d9f7facad0e1277



More information about the pld-cvs-commit mailing list