]> git.pld-linux.org Git - packages/qt4.git/blob - qt4-wkhtml.patch
- really disable openvg
[packages/qt4.git] / qt4-wkhtml.patch
1 git clone git://gitorious.org/~antialize/qt/antializes-qt.git, then checkout 4.8.4
2 # check 4.8.4 commit ID on git://gitorious.org/qt/qt.git
3 git diff 96311def2466dd44de64d77a1c815b22fbf68f71
4 # parts related to static QtWebkit build are disabled
5
6 #diff --git a/configure b/configure
7 #index e3d464b..114933e 100755
8 #--- a/configure
9 #+++ b/configure
10 #@@ -7749,12 +7749,12 @@ if [ "$CFG_GUI" = "no" ]; then
11 #     canBuildWebKit="no"
12 # fi
13
14 #-if [ "$CFG_SHARED" = "no" ]; then
15 #-    echo
16 #-    echo "WARNING: Using static linking will disable the WebKit module."
17 #-    echo
18 #-    canBuildWebKit="no"
19 #-fi
20 #+#if [ "$CFG_SHARED" = "no" ]; then
21 #+   # echo
22 #+   # echo "WARNING: Using static linking will disable the WebKit module."
23 #+   # echo
24 #+   # canBuildWebKit="no"
25 #+#fi
26
27 # CFG_CONCURRENT="yes"
28 # if [ "$canBuildQtConcurrent" = "no" ]; then
29 #diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro b/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro
30 #index a109179..146cb2d 100644
31 #--- a/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro
32 #+++ b/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pro
33 #@@ -217,6 +217,12 @@ symbian: {
34 #     QMAKE_CXXFLAGS.ARMCC += -OTime -O3
35 # }
36
37 #+static {
38 #+  !isEmpty(INSTALL_LIBS): target.path = $$INSTALL_LIBS
39 #+  else: target.path = $$[QT_INSTALL_LIBS]
40 #+  INSTALLS += target
41 #+}
42 #+
43 # lessThan(QT_GCC_MAJOR_VERSION, 5) {
44 #     # GCC 4.5 and before
45 #     lessThan(QT_GCC_MINOR_VERSION, 6) {
46 diff --git a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
47 index ef72fb7..54ff69c 100644
48 --- a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
49 +++ b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
50 @@ -1080,7 +1080,9 @@ void FrameView::adjustMediaTypeForPrinting(bool printing)
51      if (printing) {
52          if (m_mediaTypeWhenNotPrinting.isNull())
53              m_mediaTypeWhenNotPrinting = mediaType();
54 -            setMediaType("print");
55 +
56 +        String mediaType = (m_frame && m_frame->settings())?m_frame->settings()->printingMediaType():"print";
57 +        setMediaType(mediaType);
58      } else {
59          if (!m_mediaTypeWhenNotPrinting.isNull())
60              setMediaType(m_mediaTypeWhenNotPrinting);
61 diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
62 index 660ad11..8dffd52 100644
63 --- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
64 +++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
65 @@ -26,6 +26,7 @@
66  #include "FrameView.h"
67  #include "RenderLayer.h"
68  #include "RenderView.h"
69 +#include "Settings.h"
70  #include <wtf/text/StringConcatenate.h>
71  
72  namespace WebCore {
73 @@ -182,11 +183,21 @@ void PrintContext::begin(float width, float height)
74      // This function can be called multiple times to adjust printing parameters without going back to screen mode.
75      m_isPrinting = true;
76  
77 -    float minLayoutWidth = width * printingMinimumShrinkFactor;
78 -    float minLayoutHeight = height * printingMinimumShrinkFactor;
79 +    float minimumShrinkFactor = m_frame->settings() ? 
80 +        m_frame->settings()->printingMinimumShrinkFactor() : 0.0f;
81 +    float maximumShrinkFactor = m_frame->settings() ? 
82 +        m_frame->settings()->printingMaximumShrinkFactor() : 0.0f;
83 +
84 +    if (maximumShrinkFactor < minimumShrinkFactor || minimumShrinkFactor <= 0.0f) {
85 +        minimumShrinkFactor = printingMinimumShrinkFactor;
86 +        maximumShrinkFactor = printingMaximumShrinkFactor;
87 +    }
88 +    
89 +    float minLayoutWidth = width * minimumShrinkFactor;
90 +    float minLayoutHeight = height * minimumShrinkFactor;
91  
92      // This changes layout, so callers need to make sure that they don't paint to screen while in printing mode.
93 -    m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), printingMaximumShrinkFactor / printingMinimumShrinkFactor, Frame::AdjustViewSize);
94 +    m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), maximumShrinkFactor / minimumShrinkFactor, Frame::AdjustViewSize);
95  }
96  
97  float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize)
98 diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
99 index aadff47..19f378e 100644
100 --- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
101 +++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
102 @@ -83,6 +83,8 @@ public:
103      // (pageSizeInPixels.height() + 1) * number-of-pages - 1
104      static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels);
105  
106 +public:
107 +    const Vector<IntRect> & getPageRects() const {return m_pageRects;}
108  protected:
109      Frame* m_frame;
110      Vector<IntRect> m_pageRects;
111 diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
112 index 2025bd0..5414246 100644
113 --- a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
114 +++ b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
115 @@ -87,6 +87,7 @@ static EditingBehaviorType editingBehaviorTypeForPlatform()
116  
117  Settings::Settings(Page* page)
118      : m_page(page)
119 +    , m_printingMediaType("print")
120      , m_editableLinkBehavior(EditableLinkDefaultBehavior)
121      , m_textDirectionSubmenuInclusionBehavior(TextDirectionSubmenuAutomaticallyIncluded)
122      , m_passwordEchoDurationInSeconds(1)
123 @@ -184,6 +185,8 @@ Settings::Settings(Page* page)
124      , m_allowDisplayOfInsecureContent(true)
125      , m_allowRunningOfInsecureContent(true)
126      , m_passwordEchoEnabled(false)
127 +    , m_printingMinimumShrinkFactor(0.0)
128 +    , m_printingMaximumShrinkFactor(0.0)
129  {
130      // A Frame may not have been created yet, so we initialize the AtomicString 
131      // hash before trying to use it.
132 @@ -569,6 +572,11 @@ void Settings::setApplicationChromeMode(bool mode)
133      m_inApplicationChromeMode = mode;
134  }
135  
136 +void Settings::setPrintingMediaType(const String& type)
137 +{
138 +    m_printingMediaType = type;
139 +}
140 +
141  void Settings::setOfflineWebApplicationCacheEnabled(bool enabled)
142  {
143      m_offlineWebApplicationCacheEnabled = enabled;
144 @@ -744,4 +752,15 @@ void Settings::setTiledBackingStoreEnabled(bool enabled)
145  #endif
146  }
147  
148 +void Settings::setPrintingMinimumShrinkFactor(float printingMinimumShrinkFactor)
149 +{
150 +    m_printingMinimumShrinkFactor = printingMinimumShrinkFactor;
151 +}    
152 +
153 +void Settings::setPrintingMaximumShrinkFactor(float printingMaximumShrinkFactor)
154 +{
155 +    m_printingMaximumShrinkFactor = printingMaximumShrinkFactor;
156 +}    
157 +
158 +
159  } // namespace WebCore
160 diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.h b/src/3rdparty/webkit/Source/WebCore/page/Settings.h
161 index 1d2a138..d827693 100644
162 --- a/src/3rdparty/webkit/Source/WebCore/page/Settings.h
163 +++ b/src/3rdparty/webkit/Source/WebCore/page/Settings.h
164 @@ -258,6 +258,9 @@ namespace WebCore {
165          void setApplicationChromeMode(bool);
166          bool inApplicationChromeMode() const { return m_inApplicationChromeMode; }
167  
168 +        void setPrintingMediaType(const String&);
169 +        const String& printingMediaType() const { return m_printingMediaType; }
170 +
171          void setOfflineWebApplicationCacheEnabled(bool);
172          bool offlineWebApplicationCacheEnabled() const { return m_offlineWebApplicationCacheEnabled; }
173  
174 @@ -349,6 +352,12 @@ namespace WebCore {
175          
176          void setTiledBackingStoreEnabled(bool);
177          bool tiledBackingStoreEnabled() const { return m_tiledBackingStoreEnabled; }
178 +       
179 +        void setPrintingMinimumShrinkFactor(float);
180 +        float printingMinimumShrinkFactor() const { return m_printingMinimumShrinkFactor; }
181 +       
182 +        void setPrintingMaximumShrinkFactor(float);
183 +        float printingMaximumShrinkFactor() const { return m_printingMaximumShrinkFactor; }
184  
185          void setPaginateDuringLayoutEnabled(bool flag) { m_paginateDuringLayoutEnabled = flag; }
186          bool paginateDuringLayoutEnabled() const { return m_paginateDuringLayoutEnabled; }
187 @@ -419,6 +428,7 @@ namespace WebCore {
188          String m_defaultTextEncodingName;
189          String m_ftpDirectoryTemplatePath;
190          String m_localStorageDatabasePath;
191 +        String m_printingMediaType;
192          KURL m_userStyleSheetLocation;
193          AtomicString m_standardFontFamily;
194          AtomicString m_fixedFontFamily;
195 @@ -429,6 +439,8 @@ namespace WebCore {
196          EditableLinkBehavior m_editableLinkBehavior;
197          TextDirectionSubmenuInclusionBehavior m_textDirectionSubmenuInclusionBehavior;
198          double m_passwordEchoDurationInSeconds;
199 +        float m_printingMinimumShrinkFactor;
200 +        float m_printingMaximumShrinkFactor;
201          int m_minimumFontSize;
202          int m_minimumLogicalFontSize;
203          int m_defaultFontSize;
204 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
205 index c348870..4069687 100644
206 --- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
207 +++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
208 @@ -73,7 +73,8 @@ FontPlatformData::FontPlatformData(const FontDescription& description, const Ato
209      font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing);
210      const bool smallCaps = description.smallCaps();
211      font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase);
212 -    font.setStyleStrategy(QFont::ForceIntegerMetrics);
213 +    // Commented out to work around webkit bug 93263
214 +    //font.setStyleStrategy(QFont::ForceIntegerMetrics);
215  
216      m_data->bold = font.bold();
217      // WebKit allows font size zero but QFont does not. We will return
218 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
219 index 0c8ce9e..5ba54d0 100644
220 --- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
221 +++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
222 @@ -41,6 +41,7 @@
223  #include "PlatformString.h"
224  #include "StillImageQt.h"
225  #include "qwebsettings.h"
226 +#include "SharedBuffer.h"
227  
228  #include <QPixmap>
229  #include <QPainter>
230 @@ -234,7 +235,8 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
231          }
232      }
233  
234 -    ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc);
235 +    QByteArray a = QByteArray::fromRawData(data()->data(), data()->size());
236 +    ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc, &a);
237  
238      ctxt->setCompositeOperation(previousOperator);
239  
240 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
241 index 4db8bd1..0f405cb 100644
242 --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
243 +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
244 @@ -53,11 +53,17 @@ static int screenNumber(Widget* w)
245  
246  int screenDepth(Widget* w)
247  {
248 +    if (QApplication::type() == QApplication::Tty)
249 +        return 32;
250 +
251      return QApplication::desktop()->screen(screenNumber(w))->depth();
252  }
253  
254  int screenDepthPerComponent(Widget* w)
255  {
256 +    if (QApplication::type() == QApplication::Tty)
257 +        return 8;
258 +
259      int depth = QApplication::desktop()->screen(0)->depth();
260      if (w) {
261          QWebPageClient* client = w->root()->hostWindow()->platformPageClient();
262 @@ -86,17 +92,26 @@ int screenDepthPerComponent(Widget* w)
263  
264  bool screenIsMonochrome(Widget* w)
265  {
266 +    if (QApplication::type() == QApplication::Tty)
267 +        return false;
268 +
269      return QApplication::desktop()->screen(screenNumber(w))->colorCount() == 2;
270  }
271  
272  FloatRect screenRect(Widget* w)
273  {
274 +    if (QApplication::type() == QApplication::Tty)
275 +        return FloatRect(0,0,800,600);
276 +
277      QRect r = QApplication::desktop()->screenGeometry(screenNumber(w));
278      return FloatRect(r.x(), r.y(), r.width(), r.height());
279  }
280  
281  FloatRect screenAvailableRect(Widget* w)
282  {
283 +    if (QApplication::type() == QApplication::Tty)
284 +        return FloatRect(0,0,800,600);
285 +
286      QRect r = QApplication::desktop()->availableGeometry(screenNumber(w));
287      return FloatRect(r.x(), r.y(), r.width(), r.height());
288  }
289 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
290 index f98df88..b1fe30d 100644
291 --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
292 +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
293 @@ -178,7 +178,13 @@ RenderThemeQt::RenderThemeQt(Page* page)
294      : RenderTheme()
295      , m_page(page)
296      , m_lineEdit(0)
297 +    , m_fallbackStyle(0)
298  {
299 +    if (QApplication::type() == QApplication::Tty) {
300 +        m_buttonFontFamily = "sans-serif";
301 +        return;
302 +    }
303 +
304      QPushButton button;
305      button.setAttribute(Qt::WA_MacSmallSize);
306      QFont defaultButtonFont = QApplication::font(&button);
307 @@ -339,6 +345,9 @@ bool RenderThemeQt::supportsControlTints() const
308  
309  int RenderThemeQt::findFrameLineWidth(QStyle* style) const
310  {
311 +    if (QApplication::type()==QApplication::Tty)
312 +        return 1;
313 +
314  #ifndef QT_NO_LINEEDIT
315      if (!m_lineEdit)
316          m_lineEdit = new QLineEdit();
317 @@ -445,6 +454,9 @@ Color RenderThemeQt::systemColor(int cssValueId) const
318  
319  int RenderThemeQt::minimumMenuListSize(RenderStyle*) const
320  {
321 +    if (QApplication::type() == QApplication::Tty)
322 +        return 1;
323 +
324      const QFontMetrics &fm = QApplication::fontMetrics();
325      return fm.width(QLatin1Char('x'));
326  }
327 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
328 index d648c53..f844d54 100644
329 --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
330 +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
331 @@ -54,6 +54,9 @@ static QWidget* qwidgetForPage(const Page* page)
332  
333  FloatRect screenRect(const Page* page)
334  {
335 +    if (QApplication::type() == QApplication::Tty)
336 +        return FloatRect(0,0,800,600);
337 +
338      QWidget* qw = qwidgetForPage(page);
339      if (!qw)
340          return FloatRect();
341 @@ -68,6 +71,9 @@ FloatRect screenRect(const Page* page)
342  
343  int screenDepth(const Page* page)
344  {
345 +    if (QApplication::type() == QApplication::Tty)
346 +        return 32;
347 +
348      QWidget* qw = qwidgetForPage(page);
349      if (!qw)
350          return 32;
351 @@ -77,6 +83,9 @@ int screenDepth(const Page* page)
352  
353  FloatRect usableScreenRect(const Page* page)
354  {
355 +    if (QApplication::type() == QApplication::Tty)
356 +        return FloatRect();
357 +
358      QWidget* qw = qwidgetForPage(page);
359      if (!qw)
360          return FloatRect();
361 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
362 index 5215e66..e033279 100644
363 --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
364 +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
365 @@ -41,6 +41,7 @@
366  #include "QWebPageClient.h"
367  #include "ScrollView.h"
368  
369 +#include <QApplication>
370  #include <QCoreApplication>
371  #include <QDebug>
372  #include <QPaintEngine>
373 @@ -78,6 +79,9 @@ void Widget::setFocus(bool focused)
374  void Widget::setCursor(const Cursor& cursor)
375  {
376  #ifndef QT_NO_CURSOR
377 +    if (QApplication::type() == QApplication::Tty)
378 +        return;
379 +
380      ScrollView* view = root();
381      if (!view)
382          return;
383 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
384 index 2e92801..1690c2f 100644
385 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
386 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
387 @@ -956,7 +956,8 @@ void RenderBlock::layoutRunsAndFloats(bool fullLayout, bool hasInlineChild, Vect
388                      repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow());
389                  }
390  
391 -                if (paginated) {
392 +                // table cell pagination is handled in RenderTableSection
393 +                if (paginated && !isTableCell()) {
394                      int adjustment = 0;
395                      adjustLinePositionForPagination(lineBox, adjustment);
396                      if (adjustment) {
397 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
398 index f052ee7..a5afea5 100644
399 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
400 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
401 @@ -804,7 +804,8 @@ void RenderBox::paintRootBoxFillLayers(const PaintInfo& paintInfo)
402  
403      // The background of the box generated by the root element covers the entire canvas, so just use
404      // the RenderView's docTop/Left/Width/Height accessors.
405 -    paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), BackgroundBleedNone, CompositeSourceOver, bodyObject);
406 +    if (bgColor.rgb() != Color::white)
407 +        paintFillLayers(paintInfo, bgColor, bgLayer, view()->docLeft(), view()->docTop(), view()->docWidth(), view()->docHeight(), BackgroundBleedNone, CompositeSourceOver, bodyObject);
408  }
409  
410  void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
411 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
412 index 73b0801..c34b1c2 100644
413 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
414 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
415 @@ -302,11 +302,20 @@ void RenderTable::layout()
416  
417      bool collapsing = collapseBorders();
418  
419 +    // repeat header and footer on each page
420 +    int headHeight = 0;
421 +    int footHeight = 0;
422      for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
423          if (child->isTableSection()) {
424              child->layoutIfNeeded();
425              RenderTableSection* section = toRenderTableSection(child);
426 -            totalSectionLogicalHeight += section->calcRowLogicalHeight();
427 +            int rowHeight = section->calcRowLogicalHeight();
428 +            if (child == m_head) {
429 +                headHeight = rowHeight;
430 +            } else if (child == m_foot) {
431 +                footHeight = rowHeight;
432 +            }
433 +            totalSectionLogicalHeight += rowHeight;
434              if (collapsing)
435                  section->recalcOuterBorder();
436              ASSERT(!section->needsLayout());
437 @@ -320,6 +329,30 @@ void RenderTable::layout()
438      if (m_caption)
439          m_caption->layoutIfNeeded();
440  
441 +    // Bump table to next page if we can't fit the caption, thead and first body cell
442 +    setPaginationStrut(0);
443 +    if (view()->layoutState()->pageLogicalHeight()) {
444 +        LayoutState* layoutState = view()->layoutState();
445 +        const int pageLogicalHeight = layoutState->m_pageLogicalHeight;
446 +        const int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(0) % pageLogicalHeight;
447 +        if (remainingLogicalHeight > 0) {
448 +            int requiredHeight = headHeight;
449 +            if (m_caption && m_caption->style()->captionSide() != CAPBOTTOM) {
450 +                requiredHeight += m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter();
451 +            }
452 +            if (m_firstBody) {
453 +                // FIXME: Calculate maximum required height across all cells in first body row
454 +                RenderTableCell* firstCell = m_firstBody->primaryCellAt(0, 0);
455 +                if (firstCell) {
456 +                    requiredHeight += firstCell->contentLogicalHeight() + firstCell->paddingTop(false) + firstCell->paddingBottom(false) + vBorderSpacing();
457 +                }
458 +            }
459 +            if (requiredHeight > remainingLogicalHeight) {
460 +                setPaginationStrut(remainingLogicalHeight);
461 +            }
462 +        }
463 +    }
464 +
465      // If any table section moved vertically, we will just repaint everything from that
466      // section down (it is quite unlikely that any of the following sections
467      // did not shift).
468 @@ -352,12 +385,6 @@ void RenderTable::layout()
469          computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength);
470      computedLogicalHeight = max(0, computedLogicalHeight);
471  
472 -    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
473 -        if (child->isTableSection())
474 -            // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one.
475 -            toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0);
476 -    }
477 -
478      if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
479          // Completely empty tables (with no sections or anything) should at least honor specified height
480          // in strict mode.
481 @@ -377,6 +404,9 @@ void RenderTable::layout()
482          }
483          section->setLogicalLocation(sectionLogicalLeft, logicalHeight());
484  
485 +        // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one.
486 +        section->layoutRows(section == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0, section == m_head ? 0 : headHeight, section == m_foot ? 0 : footHeight);
487 +
488          setLogicalHeight(logicalHeight() + section->logicalHeight());
489          section = sectionBelow(section);
490      }
491 @@ -503,7 +533,59 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
492              child->paint(info, childPoint.x(), childPoint.y());
493          }
494      }
495 -    
496 +
497 +    bool repaintedHead = false;
498 +    IntPoint repaintedHeadPoint;
499 +    bool repaintedFoot = false;
500 +    IntPoint repaintedFootPoint;
501 +    if (view()->pageLogicalHeight()) {
502 +        // re-paint header/footer if table is split over multiple pages
503 +        if (m_head) {
504 +            IntPoint childPoint = flipForWritingMode(m_head, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
505 +            if (info.rect.y() > childPoint.y() + m_head->y()) {
506 +                repaintedHeadPoint = IntPoint(childPoint.x(), info.rect.y() - m_head->y());
507 +                repaintedHead = true;
508 +                dynamic_cast<RenderObject*>(m_head)->paint(info, repaintedHeadPoint.x(), repaintedHeadPoint.y());
509 +            }
510 +        }
511 +        if (m_foot) {
512 +            IntPoint childPoint = flipForWritingMode(m_foot, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
513 +            if (info.rect.y() + info.rect.height() < childPoint.y() + m_foot->y()) {
514 +                // find actual end of table on current page
515 +                int dy = 0;
516 +                const int max_dy = info.rect.y() + info.rect.height();
517 +                const int vspace = vBorderSpacing();
518 +                for (RenderObject* section = firstChild(); section; section = section->nextSibling()) {
519 +                    if (section->isTableSection()) {
520 +                        if (toRenderBox(section)->y() > max_dy) {
521 +                            continue;
522 +                        }
523 +                        int i = 0;
524 +                        for(RenderObject* row = section->firstChild(); row; row = row->nextSibling()) {
525 +                            if (!row->isTableRow()) {
526 +                                continue;
527 +                            }
528 +                            // get actual bottom-y position of this row - pretty complicated, how could this be simplified?
529 +                            // note how we have to take the rowPoint and section's y-offset into account, see e.g.
530 +                            // RenderTableSection::paint where this is also done...
531 +                            IntPoint rowPoint = flipForWritingMode(toRenderBox(row), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
532 +                            int row_dy = rowPoint.y() + toRenderBox(row)->y() + toRenderBox(row)->logicalHeight() + toRenderBox(section)->y();
533 +                            if (row_dy < max_dy && row_dy > dy) {
534 +                                dy = row_dy;
535 +                            } else if (row_dy > max_dy) {
536 +                                break;
537 +                            }
538 +                            i++;
539 +                        }
540 +                    }
541 +                }
542 +                repaintedFoot = true;
543 +                repaintedFootPoint = IntPoint(childPoint.x(), dy - m_foot->y());
544 +                dynamic_cast<RenderObject*>(m_foot)->paint(info, repaintedFootPoint.x(), repaintedFootPoint.y());
545 +            }
546 +        }
547 +    }
548 +
549      if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) {
550          // Collect all the unique border styles that we want to paint in a sorted list.  Once we
551          // have all the styles sorted, we then do individual passes, painting each style of border
552 @@ -522,6 +604,12 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
553              for (RenderObject* child = firstChild(); child; child = child->nextSibling())
554                  if (child->isTableSection()) {
555                      IntPoint childPoint = flipForWritingMode(toRenderTableSection(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
556 +                    // also repaint borders of header/footer if required
557 +                    if (child == m_head && repaintedHead) {
558 +                        childPoint = repaintedHeadPoint;
559 +                    } else if (child == m_foot && repaintedFoot) {
560 +                        childPoint = repaintedFootPoint;
561 +                    }
562                      child->paint(info, childPoint.x(), childPoint.y());
563                  }
564          }
565 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
566 index 7d414a0..6c814b3 100644
567 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
568 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
569 @@ -414,7 +414,7 @@ void RenderTableSection::layout()
570      setNeedsLayout(false);
571  }
572  
573 -int RenderTableSection::layoutRows(int toAdd)
574 +int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
575  {
576  #ifndef NDEBUG
577      setNeedsLayoutIsForbidden(true);
578 @@ -496,12 +496,47 @@ int RenderTableSection::layoutRows(int toAdd)
579  
580      LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
581  
582 +    // Calculate logical row heights
583 +    Vector<int> logicalRowHeights;
584 +    logicalRowHeights.resize(totalRows);
585 +    for (int r = 0; r < totalRows; r++) {
586 +        logicalRowHeights[r] = m_rowPos[r + 1] - m_rowPos[r] - vspacing;
587 +    }
588 +
589 +    // Make sure that cell contents do not overlap a page break
590 +    if (view()->layoutState()->pageLogicalHeight()) {
591 +        LayoutState* layoutState = view()->layoutState();
592 +        int pageLogicalHeight = layoutState->m_pageLogicalHeight;
593 +        int pageOffset = 0;
594 +
595 +        for (int r = 0; r < totalRows; ++r) {
596 +            int rowLogicalOffset = m_rowPos[r] + pageOffset;
597 +            int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(rowLogicalOffset) % pageLogicalHeight;
598 +
599 +            for (int c = 0; c < nEffCols; c++) {
600 +                CellStruct& cs = cellAt(r, c);
601 +                RenderTableCell* cell = cs.primaryCell();
602 +
603 +                if (!cell || cs.inColSpan || cell->row() != r)
604 +                    continue;
605 +
606 +                int cellRequiredHeight = cell->contentLogicalHeight() + cell->paddingTop(false) + cell->paddingBottom(false);
607 +                if (max(logicalRowHeights[r], cellRequiredHeight) > remainingLogicalHeight - footHeight - vspacing) {
608 +                    pageOffset += remainingLogicalHeight + headHeight;
609 +                    break;
610 +                }
611 +            }
612 +            m_rowPos[r] += pageOffset;
613 +        }
614 +        m_rowPos[totalRows] += pageOffset;
615 +    }
616 +
617      for (int r = 0; r < totalRows; r++) {
618          // Set the row's x/y position and width/height.
619          if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) {
620              rowRenderer->setLocation(0, m_rowPos[r]);
621              rowRenderer->setLogicalWidth(logicalWidth());
622 -            rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing);
623 +            rowRenderer->setLogicalHeight(logicalRowHeights[r]);
624              rowRenderer->updateLayerTransform();
625          }
626  
627 @@ -513,7 +548,11 @@ int RenderTableSection::layoutRows(int toAdd)
628                  continue;
629  
630              rindx = cell->row();
631 -            rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
632 +            if (cell->rowSpan() == 1) {
633 +                rHeight = logicalRowHeights[rindx];
634 +            } else {
635 +                rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
636 +            }
637              
638              // Force percent height children to lay themselves out again.
639              // This will cause these children to grow to fill the cell.
640 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
641 index db6edc2..9d912a0 100644
642 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
643 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
644 @@ -49,7 +49,7 @@ public:
645  
646      void setCellLogicalWidths();
647      int calcRowLogicalHeight();
648 -    int layoutRows(int logicalHeight);
649 +    int layoutRows(int logicalHeight, int headHeight, int footHeight);
650  
651      RenderTable* table() const { return toRenderTable(parent()); }
652  
653 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
654 index 4b1a758..2ad7f1f 100644
655 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
656 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
657 @@ -170,6 +170,7 @@ private:
658      friend class QWebHitTestResult;
659      friend class QWebHitTestResultPrivate;
660      friend class QWebPage;
661 +    friend class QWebPrinter;
662  
663  #if defined(WTF_USE_V8) && WTF_USE_V8
664      friend class V8::Bindings::QtWebElementRuntime;
665 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
666 index 5ea7059..b0229ed 100644
667 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
668 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
669 @@ -216,6 +216,114 @@ static inline ResourceRequestCachePolicy cacheLoadControlToCachePolicy(uint cach
670      return WebCore::UseProtocolCachePolicy;
671  }
672  
673 +#ifndef QT_NO_PRINTER
674 +QWebPrinterPrivate::QWebPrinterPrivate(const QWebFrame *f, QPaintDevice *printer, QPainter &p)
675 +    : printContext(f->d->frame)
676 +    , painter(p)
677 +    , frame(f)
678 +    , graphicsContext(&p)
679 +{
680 +    const qreal zoomFactorX = printer->logicalDpiX() / qt_defaultDpi();
681 +    const qreal zoomFactorY = printer->logicalDpiY() / qt_defaultDpi();
682 +    IntRect pageRect(0, 0,
683 +                     int(printer->width() / zoomFactorX),
684 +                     int(printer->height() / zoomFactorY));
685 +    
686 +    printContext.begin(pageRect.width(), pageRect.height());
687 +    float pageHeight = 0;
688 +    printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight);
689 +    
690 +    painter.scale(zoomFactorX, zoomFactorY);
691 +    printWidth = pageRect.width();
692 +}
693 +
694 +QWebPrinterPrivate::~QWebPrinterPrivate() 
695 +{
696 +    printContext.end();
697 +}
698 +
699 +/*!
700 +    \class QWebPrinter
701 +    \since 4.7
702 +    \brief The QWebPrinter controls printing of a \l{QWebFrame::}
703 +
704 +    \inmodule QtWebKit
705 +
706 +    \sa QWebFrame
707 +*/
708 +QWebPrinter::QWebPrinter(const QWebFrame *frame, QPaintDevice *printer, QPainter &painter)
709 +    : d(new QWebPrinterPrivate(frame, printer, painter))
710 +{}
711 +
712 +QWebPrinter::~QWebPrinter() 
713 +{
714 +    delete d; 
715 +}
716 +
717 +/*!
718 +    Print a page of the frame. \a i is  the number of the page to print, 
719 +    and must be between 1 and \fn QWebPrinter::pageCount() .
720 +*/
721 +void QWebPrinter::spoolPage(int i) const
722 +{
723 +    if (i < 1 || i > d->printContext.pageCount()) 
724 +        return;
725 +    d->printContext.spoolPage(d->graphicsContext, i - 1, d->printWidth);
726 +}
727 +
728 +/*!
729 +    Returns the number of pages of the frame when printed.
730 +*/
731 +int QWebPrinter::pageCount() const
732 +{
733 +    return d->printContext.pageCount();
734 +}
735 +
736 +QPair<int, QRectF> QWebPrinter::elementLocation(const QWebElement & e)
737 +{
738 +    //Compute a mapping from node to render object once and for all
739 +    if (d->elementToRenderObject.empty())
740 +       for (WebCore::RenderObject * o=d->frame->d->frame->document()->renderer(); o; o=o->nextInPreOrder())
741 +           if (o->node())
742 +               d->elementToRenderObject[o->node()] = o;
743 +        
744 +    if (!d->elementToRenderObject.contains(e.m_element))
745 +       return QPair<int,QRectF>(-1, QRectF());
746 +    const WebCore::RenderObject * ro = d->elementToRenderObject[e.m_element];
747 +    const Vector<IntRect> & pageRects = d->printContext.getPageRects();
748 +
749 +    WebCore::RenderView *root = toRenderView(d->frame->d->frame->document()->renderer());
750 +    //We need the scale factor, because pages are shrinked
751 +    float scale = (float)d->printWidth / (float)root->width();
752 +
753 +    QRectF r(const_cast<WebCore::RenderObject *>(ro)->absoluteBoundingBoxRect());
754 +    
755 +    int low=0;
756 +    int high=pageRects.size();
757 +    int c = r.y() + r.height() / 2;
758 +    while(low <= high) {
759 +       int m = (low+high)/2;
760 +       if(c < pageRects[m].y())
761 +           high = m-1;
762 +       else if(c > pageRects[m].maxY())
763 +           low = m +1;
764 +       else {
765 +         QRectF tr = r.translated(0, -pageRects[m].y());
766 +         return QPair<int, QRectF>(m+1, QRect(tr.x() * scale, tr.y()*scale, tr.width()*scale, tr.height()*scale));
767 +       }
768 +        
769 +    }
770 +    return QPair<int,QRectF>(-1, QRectF());
771 +}
772 +
773 +/*!
774 +    Return the painter used for printing.
775 +*/
776 +QPainter * QWebPrinter::painter() {
777 +    return &d->painter;
778 +}
779 +#endif //QT_NO_PRINTER
780 +
781  QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame,
782                               WebCore::HTMLFrameOwnerElement* ownerFrameElement,
783                               const WTF::String& frameName)
784 @@ -1434,25 +1542,8 @@ bool QWebFrame::event(QEvent *e)
785  void QWebFrame::print(QPrinter *printer) const
786  {
787      QPainter painter;
788 -    if (!painter.begin(printer))
789 -        return;
790 -
791 -    const qreal zoomFactorX = (qreal)printer->logicalDpiX() / qt_defaultDpi();
792 -    const qreal zoomFactorY = (qreal)printer->logicalDpiY() / qt_defaultDpi();
793 -
794 -    PrintContext printContext(d->frame);
795 -    float pageHeight = 0;
796 -
797 -    QRect qprinterRect = printer->pageRect();
798 -
799 -    IntRect pageRect(0, 0,
800 -                     int(qprinterRect.width() / zoomFactorX),
801 -                     int(qprinterRect.height() / zoomFactorY));
802 -
803 -    printContext.begin(pageRect.width());
804 -
805 -    printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight);
806 -
807 +    painter.begin(printer);
808 +    QWebPrinter p(this, printer, painter);
809      int docCopies;
810      int pageCopies;
811      if (printer->collateCopies()) {
812 @@ -1469,11 +1560,12 @@ void QWebFrame::print(QPrinter *printer) const
813  
814      if (fromPage == 0 && toPage == 0) {
815          fromPage = 1;
816 -        toPage = printContext.pageCount();
817 +        toPage = p.pageCount();
818      }
819      // paranoia check
820      fromPage = qMax(1, fromPage);
821 -    toPage = qMin(static_cast<int>(printContext.pageCount()), toPage);
822 +    toPage = qMin(static_cast<int>(p.pageCount()), toPage);
823 +
824      if (toPage < fromPage) {
825          // if the user entered a page range outside the actual number
826          // of printable pages, just return
827 @@ -1486,20 +1578,15 @@ void QWebFrame::print(QPrinter *printer) const
828          toPage = tmp;
829          ascending = false;
830      }
831 -
832 -    painter.scale(zoomFactorX, zoomFactorY);
833 -    GraphicsContext ctx(&painter);
834 -
835      for (int i = 0; i < docCopies; ++i) {
836          int page = fromPage;
837          while (true) {
838              for (int j = 0; j < pageCopies; ++j) {
839                  if (printer->printerState() == QPrinter::Aborted
840                      || printer->printerState() == QPrinter::Error) {
841 -                    printContext.end();
842                      return;
843                  }
844 -                printContext.spoolPage(ctx, page - 1, pageRect.width());
845 +                p.spoolPage(page);
846                  if (j < pageCopies - 1)
847                      printer->newPage();
848              }
849 @@ -1518,8 +1605,7 @@ void QWebFrame::print(QPrinter *printer) const
850          if ( i < docCopies - 1)
851              printer->newPage();
852      }
853 -
854 -    printContext.end();
855 +    painter.end();
856  }
857  #endif // QT_NO_PRINTER
858  
859 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
860 index 3c5a28e..99771f8 100644
861 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
862 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
863 @@ -21,6 +21,8 @@
864  #ifndef QWEBFRAME_H
865  #define QWEBFRAME_H
866  
867 +#define  __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
868 +
869  #include <QtCore/qobject.h>
870  #include <QtCore/qurl.h>
871  #include <QtCore/qvariant.h>
872 @@ -42,6 +44,9 @@ class QPrinter;
873  QT_END_NAMESPACE
874  
875  class QWebNetworkRequest;
876 +#ifndef QT_NO_PRINTER
877 +class QWebPrinterPrivate;
878 +#endif
879  class QWebFramePrivate;
880  class QWebPage;
881  class QWebHitTestResult;
882 @@ -103,6 +108,20 @@ private:
883      friend class QWebPage;
884  };
885  
886 +#ifndef QT_NO_PRINTER
887 +class QWEBKIT_EXPORT QWebPrinter {
888 +public:
889 +    QWebPrinter(const QWebFrame * frame, QPaintDevice * printer, QPainter &painter);
890 +    ~QWebPrinter();
891 +    void spoolPage(int i) const;
892 +    QPainter * painter();
893 +    int pageCount() const;
894 +    QPair<int, QRectF> elementLocation(const QWebElement & e);
895 +private:
896 +    QWebPrinterPrivate * d;
897 +};
898 +#endif
899 +
900  class QWEBKIT_EXPORT QWebFrame : public QObject {
901      Q_OBJECT
902      Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false)
903 @@ -228,6 +247,8 @@ private:
904      friend class QWebPage;
905      friend class QWebPagePrivate;
906      friend class QWebFramePrivate;
907 +    friend class QWebPrinterPrivate;
908 +    friend class QWebPrinter;
909      friend class DumpRenderTreeSupportQt;
910      friend class WebCore::WidgetPrivate;
911      friend class WebCore::FrameLoaderClientQt;
912 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
913 index 4108972..3698eed 100644
914 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
915 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
916 @@ -35,6 +35,9 @@
917  #include "wtf/RefPtr.h"
918  #include "Frame.h"
919  #include "ViewportArguments.h"
920 +#include <qpainter.h>
921 +#include "PrintContext.h"
922 +#include "GraphicsContext.h"
923  
924  #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
925  #include "texmap/TextureMapper.h"
926 @@ -69,6 +72,19 @@ public:
927      int marginHeight;
928  };
929  
930 +class QWebPrinterPrivate {
931 +public:
932 +    WebCore::PrintContext printContext;
933 +    QPainter & painter;
934 +    const QWebFrame * frame;
935 +    WebCore::GraphicsContext graphicsContext;
936 +    int printWidth;
937 +    QHash<const WebCore::Node*, const WebCore::RenderObject *> elementToRenderObject;
938 +    
939 +    QWebPrinterPrivate(const QWebFrame * frame, QPaintDevice *printer, QPainter &p);
940 +    ~QWebPrinterPrivate();
941 +};
942 +
943  class QWebFramePrivate {
944  public:
945      QWebFramePrivate()
946 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
947 index c1ef92e..dc4de39 100644
948 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
949 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
950 @@ -75,8 +75,11 @@ public:
951      QUrl userStyleSheetLocation;
952      QString defaultTextEncoding;
953      QString localStoragePath;
954 +    QString printingMediaType;
955      QString offlineWebApplicationCachePath;
956      qint64 offlineStorageDefaultQuota;
957 +    qreal printingMinimumShrinkFactor;
958 +    qreal printingMaximumShrinkFactor;
959  
960      void apply();
961      WebCore::Settings* settings;
962 @@ -229,9 +232,18 @@ void QWebSettingsPrivate::apply()
963          QString encoding = !defaultTextEncoding.isEmpty() ? defaultTextEncoding: global->defaultTextEncoding;
964          settings->setDefaultTextEncodingName(encoding);
965  
966 +        QString type = !printingMediaType.isEmpty() ? printingMediaType : global->printingMediaType;
967 +        settings->setPrintingMediaType(type.isEmpty() ? "print" : type);
968 +
969          QString storagePath = !localStoragePath.isEmpty() ? localStoragePath : global->localStoragePath;
970          settings->setLocalStorageDatabasePath(storagePath);
971  
972 +        float minimumShrinkFactor = printingMinimumShrinkFactor > 0.0f ? printingMinimumShrinkFactor : global->printingMinimumShrinkFactor;
973 +        settings->setPrintingMinimumShrinkFactor(minimumShrinkFactor);
974 +
975 +        float maximumShrinkFactor = printingMaximumShrinkFactor > 0.0f ? printingMaximumShrinkFactor : global->printingMaximumShrinkFactor;
976 +        settings->setPrintingMaximumShrinkFactor(maximumShrinkFactor);
977 +
978          value = attributes.value(QWebSettings::PrintElementBackgrounds,
979                                        global->attributes.value(QWebSettings::PrintElementBackgrounds));
980          settings->setShouldPrintBackgrounds(value);
981 @@ -519,6 +531,8 @@ QWebSettings::QWebSettings()
982      d->attributes.insert(QWebSettings::SiteSpecificQuirksEnabled, true);
983      d->offlineStorageDefaultQuota = 5 * 1024 * 1024;
984      d->defaultTextEncoding = QLatin1String("iso-8859-1");
985 +    d->printingMinimumShrinkFactor = 1.25f;
986 +    d->printingMaximumShrinkFactor = 2.0f;
987  }
988  
989  /*!
990 @@ -527,6 +541,8 @@ QWebSettings::QWebSettings()
991  QWebSettings::QWebSettings(WebCore::Settings* settings)
992      : d(new QWebSettingsPrivate(settings))
993  {
994 +    d->printingMinimumShrinkFactor = 0.0f;
995 +    d->printingMaximumShrinkFactor = 0.0f;
996      d->settings = settings;
997      d->apply();
998      allSettings()->append(d);
999 @@ -635,6 +651,86 @@ QString QWebSettings::defaultTextEncoding() const
1000  }
1001  
1002  /*!
1003 +    \since 4.7
1004 +    Specifies which media type to use when printing. If
1005 +    left empty the default "print" will be used, other choices include "screen". 
1006 +    See \l{http://www.w3.org/TR/CSS2/media.html}{CSS Standard}, for a complete list.
1007 +
1008 +    \sa printingMediaType()
1009 +*/
1010 +void QWebSettings::setPrintingMediaType(const QString& type)
1011 +{
1012 +    d->printingMediaType = type;
1013 +    d->apply();
1014 +}
1015 +
1016 +/*!
1017 +    \since 4.7
1018 +    Returns the media type used when printing or QString() if the
1019 +    default value is used.
1020 +
1021 +    \sa setPrintingMediaType()
1022 +*/
1023 +QString QWebSettings::printingMediaType() const
1024 +{
1025 +    return d->printingMediaType;
1026 +}
1027 +
1028 +/*!
1029 +    \since 4.6
1030 +    Specifies minimum shrink fator allowed for printing. If set to 0 a
1031 +    default value is used.
1032 +
1033 +    When printing, content will be shrunk to reduce page usage, it
1034 +    will reduced by a factor between printingMinimumShrinkFactor and
1035 +    printingMaximumShrinkFactor. 
1036 +
1037 +    \sa printingMinimumShrinkFactor()
1038 +    \sa setPrintingMaximumShrinkFactor()
1039 +    \sa printingMaximumShrinkFactor()
1040 +*/
1041 +void QWebSettings::setPrintingMinimumShrinkFactor(qreal printingMinimumShrinkFactor)
1042 +{
1043 +    d->printingMinimumShrinkFactor = printingMinimumShrinkFactor;
1044 +    d->apply();
1045 +}
1046 +
1047 +/*!
1048 +    \since 4.6
1049 +    returns the minimum shrink factor used for printing.
1050 +
1051 +    \sa setPrintingMinimumShrinkFactor()
1052 +*/
1053 +qreal QWebSettings::printingMinimumShrinkFactor() const
1054 +{
1055 +    return d->printingMinimumShrinkFactor;
1056 +}
1057 +
1058 +/*!
1059 +    \since 4.6 
1060 +    Specifies maximum shrink fator allowed for printing. If set to 0 a
1061 +    default value is used.
1062 +
1063 +    \sa setPrintingMinimumShrinkFactor()
1064 +*/
1065 +void QWebSettings::setPrintingMaximumShrinkFactor(qreal printingMaximumShrinkFactor)
1066 +{
1067 +    d->printingMaximumShrinkFactor = printingMaximumShrinkFactor;
1068 +    d->apply();
1069 +}
1070 +
1071 +/*!
1072 +    \since 4.6 
1073 +    returns the maximum shrink factor used for printing.
1074 +
1075 +    \sa setPrintingMinimumShrinkFactor()
1076 +*/
1077 +qreal QWebSettings::printingMaximumShrinkFactor() const
1078 +{
1079 +    return d->printingMaximumShrinkFactor;
1080 +}
1081 +
1082 +/*!
1083      Sets the path of the icon database to \a path. The icon database is used
1084      to store "favicons" associated with web sites.
1085  
1086 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
1087 index 008035b..bb134a3 100644
1088 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
1089 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
1090 @@ -116,6 +116,15 @@ public:
1091      void setDefaultTextEncoding(const QString &encoding);
1092      QString defaultTextEncoding() const;
1093  
1094 +    void setPrintingMediaType(const QString &type);
1095 +    QString printingMediaType() const;
1096 +
1097 +    void setPrintingMinimumShrinkFactor(qreal printingMinimumShrinkFactor);
1098 +    qreal printingMinimumShrinkFactor() const;
1099 +
1100 +    void setPrintingMaximumShrinkFactor(qreal printingMaximimShrinkFactor);
1101 +    qreal printingMaximumShrinkFactor() const;
1102 +
1103      static void setIconDatabasePath(const QString &location);
1104      static QString iconDatabasePath();
1105      static void clearIconDatabase();
1106 diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
1107 index 3fc65d3..6657879 100644
1108 --- a/src/gui/image/qpixmap.cpp
1109 +++ b/src/gui/image/qpixmap.cpp
1110 @@ -134,12 +134,6 @@ extern QApplication::Type qt_appType;
1111  
1112  void QPixmap::init(int w, int h, int type)
1113  {
1114 -    if (qt_appType == QApplication::Tty) {
1115 -        qWarning("QPixmap: Cannot create a QPixmap when no GUI is being used");
1116 -        data = 0;
1117 -        return;
1118 -    }
1119 -
1120      if ((w > 0 && h > 0) || type == QPixmapData::BitmapType)
1121          data = QPixmapData::create(w, h, (QPixmapData::PixelType) type);
1122      else
1123 diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
1124 index 5950c5d..36303a0 100644
1125 --- a/src/gui/image/qpixmap_raster.cpp
1126 +++ b/src/gui/image/qpixmap_raster.cpp
1127 @@ -47,6 +47,7 @@
1128  #include "qnativeimage_p.h"
1129  #include "qimage_p.h"
1130  #include "qpaintengine.h"
1131 +#include "kernel/qapplication_p.h"
1132  
1133  #include "qbitmap.h"
1134  #include "qimage.h"
1135 @@ -115,8 +116,10 @@ void QRasterPixmapData::resize(int width, int height)
1136  #else
1137      if (pixelType() == BitmapType)
1138          format = QImage::Format_MonoLSB;
1139 -    else
1140 +    else if (qt_is_gui_used)
1141          format = QNativeImage::systemFormat();
1142 +    else
1143 +        format = QImage::Format_RGB32;
1144  #endif
1145  
1146      image = QImage(width, height, format);
1147 @@ -431,7 +434,7 @@ void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConve
1148                      ? QImage::Format_ARGB32_Premultiplied
1149                      : QImage::Format_RGB32;
1150          } else {
1151 -            QImage::Format opaqueFormat = QNativeImage::systemFormat();
1152 +            QImage::Format opaqueFormat = qt_is_gui_used ? QNativeImage::systemFormat() : QImage::Format_RGB32;
1153              QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
1154  
1155  #if !defined(QT_HAVE_NEON) && !defined(QT_ALWAYS_HAVE_SSE2)
1156 diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
1157 index 9582abf..ebaea4b 100644
1158 --- a/src/gui/kernel/qapplication_x11.cpp
1159 +++ b/src/gui/kernel/qapplication_x11.cpp
1160 @@ -2280,6 +2280,8 @@ void qt_init(QApplicationPrivate *priv, int,
1161          QSegfaultHandler::initialize(priv->argv, priv->argc);
1162  #endif
1163          QCursorData::initialize();
1164 +    } else if (!QApplicationPrivate::graphics_system_name.isNull()) {
1165 +        QApplicationPrivate::graphics_system = QGraphicsSystemFactory::create(QApplicationPrivate::graphics_system_name);
1166      }
1167      QFont::initialize();
1168  
1169 diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
1170 index d8aefb6..37106f7 100644
1171 --- a/src/gui/kernel/qguiplatformplugin.cpp
1172 +++ b/src/gui/kernel/qguiplatformplugin.cpp
1173 @@ -85,7 +85,7 @@ QGuiPlatformPlugin *qt_guiPlatformPlugin()
1174  
1175          QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN"));
1176  #ifdef Q_WS_X11
1177 -        if (key.isEmpty()) {
1178 +        if (QApplication::type() != QApplication::Tty && key.isEmpty()) {
1179              switch(X11->desktopEnvironment) {
1180              case DE_KDE:
1181                  key = QString::fromLatin1("kde");
1182 diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
1183 index cd7075e..74508b3 100644
1184 --- a/src/gui/painting/qpaintengine.h
1185 +++ b/src/gui/painting/qpaintengine.h
1186 @@ -162,6 +162,19 @@ public:
1187      virtual void drawRects(const QRect *rects, int rectCount);
1188      virtual void drawRects(const QRectF *rects, int rectCount);
1189  
1190 +    virtual void addHyperlink(const QRectF &r, const QUrl &url) {Q_UNUSED(r); Q_UNUSED(url);}
1191 +    virtual void addAnchor(const QRectF &r, const QString &name) {Q_UNUSED(r); Q_UNUSED(name);}
1192 +    virtual void addLink(const QRectF &r, const QString &anchor) {Q_UNUSED(r); Q_UNUSED(anchor);}
1193 +    virtual void addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength) {
1194 +        Q_UNUSED(r); Q_UNUSED(text); Q_UNUSED(name); Q_UNUSED(multiLine); Q_UNUSED(password); Q_UNUSED(readOnly); Q_UNUSED(maxLength);
1195 +    }
1196 +    virtual void addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) {
1197 +        Q_UNUSED(r); Q_UNUSED(checked); Q_UNUSED(name); Q_UNUSED(readOnly);
1198 +    }
1199 +    virtual void addRadioButton(const QRectF &r, const QString & group="", bool checked=false, const QString &name="", bool readOnly=false) {
1200 +        Q_UNUSED(r); Q_UNUSED(checked); Q_UNUSED(name); Q_UNUSED(readOnly); Q_UNUSED(group);
1201 +    }
1202 +
1203      virtual void drawLines(const QLine *lines, int lineCount);
1204      virtual void drawLines(const QLineF *lines, int lineCount);
1205  
1206 @@ -177,6 +190,10 @@ public:
1207      virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
1208  
1209      virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) = 0;
1210 +    virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data) {
1211 +               Q_UNUSED(data);
1212 +               drawPixmap(r,pm,sr);
1213 +       }
1214      virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
1215      virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
1216      virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
1217 diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
1218 index 10ca689..d690761 100644
1219 --- a/src/gui/painting/qpaintengine_raster.cpp
1220 +++ b/src/gui/painting/qpaintengine_raster.cpp
1221 @@ -2243,11 +2243,11 @@ namespace {
1222  /*!
1223      \reimp
1224  */
1225 -void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
1226 +void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &_img, const QRectF &_sr,
1227                                     Qt::ImageConversionFlags)
1228  {
1229  #ifdef QT_DEBUG_DRAW
1230 -    qDebug() << " - QRasterPaintEngine::drawImage(), r=" << r << " sr=" << sr << " image=" << img.size() << "depth=" << img.depth();
1231 +    qDebug() << " - QRasterPaintEngine::drawImage(), r=" << r << " sr=" << _sr << " image=" << _img.size() << "depth=" << img.depth();
1232  #endif
1233  
1234      if (r.isEmpty())
1235 @@ -2255,6 +2255,17 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
1236  
1237      Q_D(QRasterPaintEngine);
1238      QRasterPaintEngineState *s = state();
1239 +    
1240 +    QImage img;
1241 +    QRectF sr=_sr;
1242 +    if (s->matrix.isAffine()) {
1243 +        img = _img.copy(sr.toRect()).scaled(
1244 +            s->matrix.mapRect(r).size().toSize(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1245 +        sr = img.rect();
1246 +    } else {
1247 +        img=_img;
1248 +    }
1249
1250      int sr_l = qFloor(sr.left());
1251      int sr_r = qCeil(sr.right()) - 1;
1252      int sr_t = qFloor(sr.top());
1253 diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
1254 index 30f986d..7836b5a 100644
1255 --- a/src/gui/painting/qpainter.cpp
1256 +++ b/src/gui/painting/qpainter.cpp
1257 @@ -5393,7 +5393,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
1258      }
1259  }
1260  
1261 -void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
1262 +void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data)
1263  {
1264  #if defined QT_DEBUG_DRAW
1265      if (qt_show_painter_debug_output)
1266 @@ -5518,7 +5518,7 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
1267              x += d->state->matrix.dx();
1268              y += d->state->matrix.dy();
1269          }
1270 -        d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
1271 +        d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh), data);
1272      }
1273  }
1274  
1275 @@ -7254,6 +7254,200 @@ void QPainter::fillRect(const QRectF &r, const QColor &color)
1276      \since 4.5
1277  */
1278  
1279 +
1280 +/*!
1281 +    \fn void QPainter::addAnchor(int x, int y, int w, int h, const QString &name);
1282 +
1283 +    \overload
1284 +
1285 +    Add an anchor to the current page at the rect specified by \a x, \a y, \a w and \a h  
1286 +    named \a name.
1287 +
1288 +    Note that for output formats not supporting links, currently all other then PDF,
1289 +    this call has no effect.
1290 +
1291 +    \sa addLink()
1292 +
1293 +    \since 4.7
1294 +*/
1295 +
1296 +/*!
1297 +    \fn void QPainter::addAnchor(const QRect &r, const QString &name);
1298 +
1299 +    \overload
1300 +
1301 +    Add an anchor to the current page at the rect specified by \a r named \a name.
1302 +
1303 +    Note that for output formats not supporting links, currently all other then PDF,
1304 +    this call has no effect.
1305 +
1306 +    \sa addLink()
1307 +
1308 +    \since 4.7
1309 +*/
1310 +
1311 +/*!
1312 +    \fn void addAnchor(const QRectF &r, const QString &name);
1313 +
1314 +    \overload
1315 +
1316 +    Add an anchor to the current page at the rect specified by \a r named \a name.
1317 +
1318 +    Note that for output formats not supporting links, currently all other then PDF,
1319 +    this call has no effect.
1320 +
1321 +    \sa addLink()
1322 +
1323 +    \since 4.7
1324 +*/
1325 +void QPainter::addAnchor(const QRectF &r, const QString &name)
1326 +{
1327 +    Q_D(QPainter);
1328 +    if (!d->engine) {
1329 +        qWarning("QPainter::addAnchor: Painter not active");
1330 +        return;
1331 +    }
1332 +    d->engine->addAnchor(worldTransform().mapRect(r), name);
1333 +}
1334 +
1335 +/*!
1336 +    \fn void QPainter::addLink(int x, int y, int w, int h, const QString &anchor);
1337 +
1338 +    \overload
1339 +
1340 +    Add a link to the current page at the rect specified by \a x, \a y, \a w and \a h  
1341 +    linking to the anchor named \a anchor.
1342 +
1343 +    Note that for output formats not supporting links, currently all other then PDF,
1344 +    this call has no effect.
1345 +
1346 +    \sa addAnchor()
1347 +
1348 +    \since 4.7
1349 +*/
1350 +
1351 +/*!
1352 +    \fn void QPainter::addLink(const QRect &r, const QString &anchor);
1353 +
1354 +    \overload
1355 +
1356 +    Add a link to the current page at the rect specified by \a r  
1357 +    linking to the anchor named \a anchor.
1358 +
1359 +    Note that for output formats not supporting links, currently all other then PDF,
1360 +    this call has no effect.
1361 +
1362 +    \sa addAnchor()
1363 +
1364 +    \since 4.7
1365 +*/
1366 +
1367 +/*!
1368 +    \fn void QPainter::addLink(const QRectF &r, const QString &anchor);
1369 +
1370 +    \overload
1371 +
1372 +    Add a link to the current page at the rect specified by \a r  
1373 +    linking to the anchor named \a anchor.
1374 +
1375 +    Note that for output formats not supporting links, currently all other then PDF,
1376 +    this call has no effect.
1377 +
1378 +    \sa addAnchor()
1379 +
1380 +    \since 4.7
1381 +*/
1382 +void QPainter::addLink(const QRectF &r, const QString &anchor)
1383 +{
1384 +    Q_D(QPainter);
1385 +    if (!d->engine) {
1386 +        qWarning("QPainter::addLink: Painter not active");
1387 +        return;
1388 +    }
1389 +    
1390 +    d->engine->addLink(worldTransform().mapRect(r), anchor);
1391 +}
1392 +
1393 +
1394 +/*!
1395 +    \fn void QPainter::addHyperlink(int x, int y, int w, int h, const QUrl &url);
1396 +
1397 +    \overload
1398 +
1399 +    Add a link to the current page at the rect specified by \a x, \a y, \a w and \a h  
1400 +    linking to \a url.
1401 +
1402 +    Note that for output formats not supporting links, currently all other then PDF,
1403 +    this call has no effect.
1404 +
1405 +    \since 4.7
1406 +*/
1407 +
1408 +/*!
1409 +    \fn void QPainter::addHyperlink(const QRect &r, const QUrl &url);
1410 +
1411 +    \overload
1412 +
1413 +    Add a link to the current page at the rect specified by \a r
1414 +    linking to \a url.
1415 +
1416 +    Note that for output formats not supporting links, currently all other then PDF,
1417 +    this call has no effect.
1418 +
1419 +    \since 4.7
1420 +*/
1421 +
1422 +/*!
1423 +    \fn void QPainter::addHyperlink(const QRectF &r, const QUrl &url);
1424 +
1425 +    \overload
1426 +
1427 +    Add a link to the current page at the rect specified by \a r
1428 +    linking to \a url.
1429 +
1430 +    Note that for output formats not supporting links, currently all other then PDF,
1431 +    this call has no effect.
1432 +
1433 +    \since 4.7
1434 +*/
1435 +void QPainter::addHyperlink(const QRectF &r, const QUrl &url)
1436 +{
1437 +    Q_D(QPainter);
1438 +    if (!d->engine) {
1439 +        qWarning("QPainter::addHyperlink: Painter not active");
1440 +        return;
1441 +    }
1442 +    d->engine->addHyperlink(worldTransform().mapRect(r), url);
1443 +}
1444 +
1445 +void QPainter::addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength) {
1446 +    Q_D(QPainter);
1447 +    if (!d->engine) {
1448 +        qWarning("QPainter::addTextField: Painter not active");
1449 +        return;
1450 +    }
1451 +    d->engine->addTextField(worldTransform().mapRect(r), text, name, multiLine, password, readOnly, maxLength);
1452 +}
1453 +
1454 +void QPainter::addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) {
1455 +    Q_D(QPainter);
1456 +    if (!d->engine) {
1457 +        qWarning("QPainter::addCheckBox: Painter not active");
1458 +        return;
1459 +    }
1460 +    d->engine->addCheckBox(worldTransform().mapRect(r), checked, name, readOnly);
1461 +}
1462 +
1463 +
1464 +void QPainter::addRadioButton(const QRectF &r, const QString & group, bool checked, const QString &name, bool readOnly) {
1465 +    Q_D(QPainter);
1466 +    if (!d->engine) {
1467 +        qWarning("QPainter::addRadioButton: Painter not active");
1468 +        return;
1469 +    }
1470 +    d->engine->addRadioButton(worldTransform().mapRect(r), group, checked, name, readOnly);
1471 +}
1472 +
1473  /*!
1474      Sets the given render \a hint on the painter if \a on is true;
1475      otherwise clears the render hint.
1476 diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
1477 index f0312e5..d853a9b 100644
1478 --- a/src/gui/painting/qpainter.h
1479 +++ b/src/gui/painting/qpainter.h
1480 @@ -364,7 +364,7 @@ public:
1481      inline void drawPicture(const QPoint &p, const QPicture &picture);
1482  #endif
1483  
1484 -    void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect);
1485 +    void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect, const QByteArray * data=0);
1486      inline void drawPixmap(const QRect &targetRect, const QPixmap &pixmap, const QRect &sourceRect);
1487      inline void drawPixmap(int x, int y, int w, int h, const QPixmap &pm,
1488                             int sx, int sy, int sw, int sh);
1489 @@ -447,6 +447,22 @@ public:
1490      inline void fillRect(const QRect &r, Qt::BrushStyle style);
1491      inline void fillRect(const QRectF &r, Qt::BrushStyle style);
1492  
1493 +    inline void addAnchor(int x, int y, int w, int h, const QString &name);
1494 +    inline void addAnchor(const QRect &r, const QString &name);
1495 +    void addAnchor(const QRectF &r, const QString &name);
1496 +
1497 +    inline void addLink(int x, int y, int w, int h, const QString &anchor);
1498 +    inline void addLink(const QRect &r, const QString &anchor);
1499 +    void addLink(const QRectF &r, const QString &anchor);
1500 +    
1501 +    void addTextField(const QRectF &r, const QString &text="", const QString &name="", bool multiLine=false, bool password=false, bool readOnly=false, int maxLength=-1);
1502 +    void addCheckBox(const QRectF &r, bool checked=false, const QString &name="", bool readOnly=false);
1503 +    void addRadioButton(const QRectF &r, const QString & group="",  bool checked=false, const QString &name="", bool readOnly=false);;
1504 +
1505 +    inline void addHyperlink(int x, int y, int w, int h, const QUrl &url);
1506 +    inline void addHyperlink(const QRect &r, const QUrl &url);
1507 +    void addHyperlink(const QRectF &r, const QUrl &url);
1508 +    
1509      void eraseRect(const QRectF &);
1510      inline void eraseRect(int x, int y, int w, int h);
1511      inline void eraseRect(const QRect &);
1512 @@ -821,6 +837,35 @@ inline void QPainter::fillRect(const QRectF &r, Qt::BrushStyle style)
1513      fillRect(r, QBrush(style));
1514  }
1515  
1516 +inline void QPainter::addAnchor(int x, int y, int w, int h, const QString &name) 
1517 +{
1518 +    addAnchor(QRectF(x, y, w, h), name);
1519 +}
1520 +
1521 +inline void QPainter::addAnchor(const QRect &r, const QString &name)
1522 +{
1523 +    addAnchor(QRectF(r), name);
1524 +}
1525 +
1526 +inline void QPainter::addLink(int x, int y, int w, int h, const QString &anchor)
1527 +{
1528 +    addLink(QRectF(x, y, w, h), anchor);
1529 +}
1530 +
1531 +inline void QPainter::addLink(const QRect &r, const QString &anchor)
1532 +{
1533 +    addLink(QRectF(r), anchor);
1534 +}
1535 +
1536 +inline void QPainter::addHyperlink(int x, int y, int w, int h, const QUrl &url)
1537 +{
1538 +    addHyperlink(QRectF(x, y, w, h), url);
1539 +}
1540 +
1541 +inline void QPainter::addHyperlink(const QRect &r, const QUrl &url)
1542 +{
1543 +    addHyperlink(QRectF(r), url);
1544 +}
1545  
1546  inline void QPainter::setBrushOrigin(int x, int y)
1547  {
1548 diff --git a/src/gui/painting/qprintengine.h b/src/gui/painting/qprintengine.h
1549 index 83bbf96..809b51a 100644
1550 --- a/src/gui/painting/qprintengine.h
1551 +++ b/src/gui/painting/qprintengine.h
1552 @@ -90,6 +90,9 @@ public:
1553          PPK_SupportsMultipleCopies,
1554          PPK_PaperSize = PPK_PageSize,
1555  
1556 +        PPK_UseCompression,
1557 +        PPK_ImageQuality, 
1558 +        PPK_ImageDPI,
1559          PPK_CustomBase = 0xff00
1560      };
1561  
1562 @@ -97,6 +100,8 @@ public:
1563      virtual QVariant property(PrintEnginePropertyKey key) const = 0;
1564  
1565      virtual bool newPage() = 0;
1566 +    virtual void beginSectionOutline(const QString &text, const QString &anchor) {Q_UNUSED(text); Q_UNUSED(anchor);}
1567 +    virtual void endSectionOutline() {}
1568      virtual bool abort() = 0;
1569  
1570      virtual int metric(QPaintDevice::PaintDeviceMetric) const = 0;
1571 diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
1572 index 239a94f..36eec2e 100644
1573 --- a/src/gui/painting/qprintengine_pdf.cpp
1574 +++ b/src/gui/painting/qprintengine_pdf.cpp
1575 @@ -51,6 +51,7 @@
1576  #include <qimagewriter.h>
1577  #include <qbuffer.h>
1578  #include <qdatetime.h>
1579 +#include <QCryptographicHash>
1580  
1581  #ifndef QT_NO_PRINTER
1582  #include <limits.h>
1583 @@ -77,12 +78,6 @@ extern qint64 qt_image_id(const QImage &image);
1584  // Can't use it though, as gs generates completely wrong images if this is true.
1585  static const bool interpolateImages = false;
1586  
1587 -#ifdef QT_NO_COMPRESS
1588 -static const bool do_compress = false;
1589 -#else
1590 -static const bool do_compress = true;
1591 -#endif
1592 -
1593  QPdfPage::QPdfPage()
1594      : QPdf::ByteStream(true) // Enable file backing
1595  {
1596 @@ -109,6 +104,30 @@ inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()
1597      return f;
1598  }
1599  
1600 +void QPdfEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) {
1601 +    Q_D(QPdfEngine);
1602 +    if (key==PPK_UseCompression)
1603 +        d->doCompress = value.toBool();
1604 +    else if (key==PPK_ImageQuality)
1605 +        d->imageQuality = value.toInt();
1606 +    else if (key==PPK_ImageDPI)
1607 +        d->imageDPI = value.toInt();
1608 +    else 
1609 +        QPdfBaseEngine::setProperty(key, value);
1610 +}
1611 +
1612 +QVariant QPdfEngine::property(PrintEnginePropertyKey key) const {
1613 +    Q_D(const QPdfEngine);
1614 +    if (key==PPK_UseCompression)
1615 +        return d->doCompress;
1616 +    else if (key==PPK_ImageQuality)
1617 +        return d->imageQuality;
1618 +    else if (key==PPK_ImageDPI)
1619 +        return d->imageDPI;
1620 +    else
1621 +        return QPdfBaseEngine::property(key);
1622 +}
1623 +
1624  QPdfEngine::QPdfEngine(QPrinter::PrinterMode m)
1625      : QPdfBaseEngine(*new QPdfEnginePrivate(m), qt_pdf_decide_features())
1626  {
1627 @@ -156,6 +175,59 @@ bool QPdfEngine::begin(QPaintDevice *pdev)
1628  bool QPdfEngine::end()
1629  {
1630      Q_D(QPdfEngine);
1631 +       
1632 +    uint dests;
1633 +    if (d->anchors.size()) {
1634 +        dests = d->addXrefEntry(-1);
1635 +        d->xprintf("<<\n");
1636 +        for (QHash<QString, uint>::iterator i=d->anchors.begin();
1637 +             i != d->anchors.end(); ++i) {
1638 +            d->printAnchor(i.key());
1639 +            d->xprintf(" %d 0 R\n", i.value());
1640 +        }
1641 +        d->xprintf(">>\n");
1642 +    }  
1643 +
1644 +    if (d->outlineRoot) {
1645 +        d->outlineRoot->obj = d->requestObject();
1646 +        d->writeOutlineChildren(d->outlineRoot);
1647 +        d->addXrefEntry(d->outlineRoot->obj);
1648 +        d->xprintf("<</Type /Outlines /First %d 0 R\n/Last %d 0 R>>\nendobj\n",
1649 +                   d->outlineRoot->firstChild->obj, d->outlineRoot->lastChild->obj);
1650 +    }
1651 +    
1652 +    if (d->formFields.size()) {
1653 +        uint font = d->addXrefEntry(-1);
1654 +        d->xprintf("<</Type/Font/Name/Helv/BaseFont/Helvetica/Subtype/Type1>>\n"
1655 +                   "endobj\n");
1656 +        d->addXrefEntry(d->formFieldList);
1657 +        d->xprintf("<</Fields[");
1658 +        foreach(const uint & i, d->formFields)
1659 +           d->xprintf("%d 0 R ",i);
1660 +        d->xprintf("]\n"
1661 +                   "/DR<</Font<</Helv %d 0 R>>>>\n"
1662 +                   "/DA(/Helv 0 Tf 0 g)\n"
1663 +                   ">>\n"
1664 +                   "endobj\n", font);
1665 +    }
1666 +
1667 +    d->catalog = d->addXrefEntry(-1);
1668 +    d->xprintf("<<\n"
1669 +               "/Type /Catalog\n"
1670 +               "/Pages %d 0 R\n", d->pageRoot);
1671 +    if (d->outlineRoot)
1672 +        d->xprintf("/Outlines %d 0 R\n"
1673 +                   "/PageMode /UseOutlines\n", d->outlineRoot->obj);
1674 +
1675 +    if (d->formFields.size()) 
1676 +        d->xprintf("/AcroForm %d 0 R\n", d->formFieldList);
1677 +
1678 +    if (d->anchors.size())
1679 +        d->xprintf("/Dests %d 0 R\n", dests);
1680 +
1681 +    d->xprintf(">>\n"
1682 +               "endobj\n");
1683 +
1684      d->writeTail();
1685  
1686      d->stream->unsetDevice();
1687 @@ -165,8 +237,83 @@ bool QPdfEngine::end()
1688      return true;
1689  }
1690  
1691 +void QPdfEngine::addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) {
1692 +    Q_D(QPdfEngine);
1693 +    uint obj = d->addXrefEntry(-1);
1694 +    char buf[256];
1695 +    QRectF rr = d->pageMatrix().mapRect(r);
1696 +    //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
1697 +    if (d->formFieldList == -1) d->formFieldList = d->requestObject();
1698 +    d->xprintf("<<\n"
1699 +               "/Type /Annot\n"
1700 +               "/Parrent %d 0 R\n"
1701 +               "/Rect[", d->formFieldList);
1702 +    d->xprintf("%s ", qt_real_to_string(rr.left(),buf));
1703 +    d->xprintf("%s ", qt_real_to_string(rr.top(),buf));
1704 +    d->xprintf("%s ", qt_real_to_string(rr.right(),buf));
1705 +    d->xprintf("%s", qt_real_to_string(rr.bottom(),buf));
1706 +    d->xprintf("]\n"
1707 +               "/FT/Btn\n"
1708 +               "/Subtype/Widget\n"
1709 +               "/P %d 0 R\n", d->pages.back());
1710 +    if (checked)
1711 +        d->xprintf("/AS /Yes\n");
1712 +    if (!name.isEmpty()) {
1713 +        d->xprintf("/T");
1714 +        d->printString(name);
1715 +        d->xprintf("\n");
1716 +    }
1717 +    d->xprintf("/Ff %d\n"
1718 +               ">>\n"
1719 +               "endobj\n",
1720 +               (readOnly?1:0)<<0);
1721 +    d->currentPage->annotations.push_back(obj);
1722 +    d->formFields.push_back(obj);
1723 +}
1724 +
1725 +void QPdfEngine::addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength)
1726 +{
1727 +    Q_D(QPdfEngine);
1728 +    uint obj = d->addXrefEntry(-1);
1729 +    char buf[256];
1730 +    QRectF rr = d->pageMatrix().mapRect(r);
1731 +    if (d->formFieldList == -1) d->formFieldList = d->requestObject();
1732 +    d->xprintf("<<\n"
1733 +               "/Type /Annot\n"
1734 +               "/Parrent %d 0 R\n"
1735 +               "/Rect[", d->formFieldList);
1736 +    d->xprintf("%s ", qt_real_to_string(rr.left(),buf));
1737 +    d->xprintf("%s ", qt_real_to_string(rr.top(),buf));
1738 +    d->xprintf("%s ", qt_real_to_string(rr.right(),buf));
1739 +    d->xprintf("%s", qt_real_to_string(rr.bottom(),buf));
1740 +    d->xprintf("]\n"
1741 +               "/BS<</S/I>>\n"
1742 +               "/FT/Tx\n"
1743 +               "/Subtype/Widget\n"
1744 +               "/P %d 0 R\n", d->pages.back());
1745 +    if (!text.isEmpty()) {
1746 +        d->xprintf("/V");
1747 +        d->printString(text);
1748 +        d->xprintf("\n");
1749 +    }
1750 +    if (!name.isEmpty()) {
1751 +        d->xprintf("/T");
1752 +        d->printString(name);
1753 +        d->xprintf("\n");
1754 +    }
1755 +    if (maxLength >= 0) 
1756 +        d->xprintf("/MaxLen %d\n",maxLength);
1757 +    d->xprintf("/DA(/Helv 12 Tf 0 g)\n"
1758 +               "/Ff %d\n"
1759 +               ">>\n"
1760 +               "endobj\n",
1761 +               (readOnly?1:0)<<0 | (password?1:0)<<13 | (multiLine?1:0)<<12
1762 +        );
1763 +    d->currentPage->annotations.push_back(obj);
1764 +    d->formFields.push_back(obj);
1765 +}
1766  
1767 -void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr)
1768 +void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr, const QByteArray * data)
1769  {
1770      if (sr.isEmpty() || rectangle.isEmpty() || pixmap.isNull())
1771          return;
1772 @@ -176,22 +323,35 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con
1773  
1774      QRect sourceRect = sr.toRect();
1775      QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap;
1776 -    QImage image = pm.toImage();
1777 +    QImage unscaled = pm.toImage();
1778 +    QImage image = unscaled;
1779 +    
1780 +    QRectF a = d->stroker.matrix.mapRect(rectangle);
1781 +    QRectF c = d->paperRect();
1782 +    int maxWidth = int(a.width() / c.width() * d->width() / 72.0 * d->imageDPI);
1783 +    int maxHeight = int(a.height() / c.height() * d->height() / 72.0 * d->imageDPI);
1784 +    if (image.width() > maxWidth || image.height() > maxHeight)
1785 +        image = unscaled.scaled( image.size().boundedTo( QSize(maxWidth, maxHeight) ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1786 +    
1787 +    bool useScaled=true;
1788      bool bitmap = true;
1789 -    const int object = d->addImage(image, &bitmap, pm.cacheKey());
1790 +    const int object = d->addImage(image, &bitmap, pm.cacheKey(), &unscaled, (sr == pixmap.rect()?data:0), &useScaled );
1791 +    int width = useScaled?image.width():unscaled.width();
1792 +    int height = useScaled?image.height():unscaled.height();
1793 +
1794      if (object < 0)
1795          return;
1796  
1797      *d->currentPage << "q\n/GSa gs\n";
1798      *d->currentPage
1799 -        << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
1800 +        << QPdf::generateMatrix(QTransform(rectangle.width() / width, 0, 0, rectangle.height() / height,
1801                                             rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
1802      if (bitmap) {
1803          // set current pen as d->brush
1804          d->brush = d->pen.brush();
1805      }
1806      setBrush();
1807 -    d->currentPage->streamImage(image.width(), image.height(), object);
1808 +    d->currentPage->streamImage(width, height, object);
1809      *d->currentPage << "Q\n";
1810  
1811      d->brush = b;
1812 @@ -301,18 +461,68 @@ QPdfEnginePrivate::QPdfEnginePrivate(QPrinter::PrinterMode m)
1813      : QPdfBaseEnginePrivate(m)
1814  {
1815      streampos = 0;
1816 -
1817 +    doCompress = true;
1818 +    imageDPI = 1400;
1819 +    imageQuality = 94;
1820      stream = new QDataStream;
1821      pageOrder = QPrinter::FirstPageFirst;
1822      orientation = QPrinter::Portrait;
1823 +    outlineRoot = NULL;
1824 +    outlineCurrent = NULL;
1825      fullPage = false;
1826  }
1827  
1828  QPdfEnginePrivate::~QPdfEnginePrivate()
1829  {
1830 +    if (outlineRoot)
1831 +      delete outlineRoot;
1832      delete stream;
1833  }
1834  
1835 +void QPdfEnginePrivate::printAnchor(const QString &name) {
1836 +    QByteArray a = name.toUtf8();
1837 +    if (a.size() >= 127)
1838 +        a = QCryptographicHash::hash(a,QCryptographicHash::Sha1);
1839 +    xprintf("/");
1840 +    for (int i=0; i < a.size(); ++i) {
1841 +        unsigned char c = a[i];
1842 +        if (('a' <= c && c <= 'z') ||
1843 +            ('A' <= c && c <= 'Z') ||
1844 +            ('0' <= c && c <= '9') ||
1845 +            c == '.' || c == '_') 
1846 +            xprintf("%c", c);
1847 +        else if(c == 0)
1848 +            xprintf("!");
1849 +        else
1850 +            xprintf("#%02x", c);
1851 +    }
1852 +}
1853 +
1854 +void QPdfEnginePrivate::writeOutlineChildren(OutlineItem * node) {
1855 +    for (OutlineItem * i = node->firstChild; i != NULL; i = i->next)
1856 +       i->obj = requestObject();
1857 +    for (OutlineItem * i = node->firstChild; i != NULL; i = i->next) {
1858 +       QPdfEnginePrivate::writeOutlineChildren(i);
1859 +       addXrefEntry(i->obj);
1860 +       xprintf("<</Title ");
1861 +       printString(i->text);
1862 +       xprintf("\n"
1863 +               "  /Parent %d 0 R\n"
1864 +               "  /Dest ", i->parent->obj);
1865 +       printAnchor(i->anchor);
1866 +       xprintf("\n  /Count 0\n");
1867 +       if (i->next)
1868 +           xprintf("  /Next %d 0 R\n", i->next->obj);
1869 +       if (i->prev)
1870 +           xprintf("  /Prev %d 0 R\n", i->prev->obj);
1871 +       if (i->firstChild)
1872 +           xprintf("  /First %d 0 R\n", i->firstChild->obj);
1873 +       if (i->lastChild)
1874 +           xprintf("  /Last %d 0 R\n", i->lastChild->obj);
1875 +       xprintf(">>\n"
1876 +               "endobj\n");
1877 +    }
1878 +}
1879  
1880  #ifdef USE_NATIVE_GRADIENTS
1881  int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject)
1882 @@ -520,10 +730,112 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
1883      return patternObj;
1884  }
1885  
1886 +
1887 +void QPdfEnginePrivate::convertImage(const QImage & image, QByteArray & imageData) {
1888 +    int w = image.width();
1889 +    int h = image.height();
1890 +    imageData.resize(colorMode == QPrinter::GrayScale ? w * h : 3 * w * h);
1891 +    uchar *data = (uchar *)imageData.data();
1892 +    for (int y = 0; y < h; ++y) {
1893 +        const QRgb *rgb = (const QRgb *)image.scanLine(y);
1894 +        if (colorMode == QPrinter::GrayScale) {
1895 +            for (int x = 0; x < w; ++x) {
1896 +                *(data++) = qGray(*rgb);
1897 +                ++rgb;
1898 +            }
1899 +        } else {
1900 +            for (int x = 0; x < w; ++x) {
1901 +                *(data++) = qRed(*rgb);
1902 +                *(data++) = qGreen(*rgb);
1903 +                *(data++) = qBlue(*rgb);
1904 +                ++rgb;
1905 +            }
1906 +        }
1907 +    }
1908 +}
1909 +
1910 +#include <iostream>
1911 +
1912 +class jpg_header_reader {
1913 +private:
1914 +  const QByteArray * data;
1915 +  int index;
1916 +  
1917 +  class jpeg_exception {};
1918 +  
1919 +  unsigned char next() {
1920 +    if (index == data->size()) throw jpeg_exception();
1921 +    return data->data()[index++];
1922 +  }
1923 +    
1924 +  void skip() {
1925 +    int l = (next() << 8) + next();
1926 +    if (l < 2) throw jpeg_exception();
1927 +    for (int i=2; i < l; ++i) next();
1928 +  }
1929 +
1930 +  void read_header() {
1931 +    int l = (next() << 8) + next();
1932 +    if (l < 2) throw jpeg_exception();
1933 +    precision = next();
1934 +    height = (next() << 8) + next();
1935 +    width = (next() << 8) + next();
1936 +    components = next();
1937 +    if (l != 8 + components*3) throw jpeg_exception();
1938 +  }
1939 +  
1940 +public:
1941 +  bool read(const QByteArray * d) {
1942 +    index=0;
1943 +    data=d;
1944 +    try {
1945 +      if (next() != 0xFF) throw jpeg_exception();
1946 +      unsigned char marker = next();
1947 +      if (marker != 0xD8) throw jpeg_exception();
1948 +      while (true) {
1949 +       marker = next();
1950 +       while (marker != 0xFF) marker=next();
1951 +       while (marker == 0xFF) marker=next();
1952 +       switch(marker) {
1953 +       case 0xC0:
1954 +       case 0xC1:
1955 +       case 0xC2:
1956 +       case 0xC3:
1957 +       case 0xC5:
1958 +       case 0xC6:
1959 +       case 0xC7:
1960 +       case 0xC9:
1961 +       case 0xCA:
1962 +       case 0xCB:
1963 +       case 0xCD:
1964 +       case 0xCE:
1965 +       case 0xCF:
1966 +         read_header();
1967 +         return true;
1968 +       case 0xDA:
1969 +       case 0xD9:
1970 +         return false;
1971 +       default:
1972 +         skip();
1973 +         break;
1974 +       }
1975 +      }
1976 +    } catch(jpeg_exception) {
1977 +      return false;
1978 +    }
1979 +    return true;
1980 +  }
1981 +
1982 +  int precision, height, width, components;
1983 +    
1984 +};
1985 +
1986 +
1987 +
1988  /*!
1989   * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
1990   */
1991 -int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no)
1992 +int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no, const QImage * noneScaled, const QByteArray * data, bool * useScaled)
1993  {
1994      if (img.isNull())
1995          return -1;
1996 @@ -564,65 +876,97 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
1997          }
1998          object = writeImage(data, w, h, d, 0, 0);
1999      } else {
2000 -        QByteArray softMaskData;
2001 -        bool dct = false;
2002          QByteArray imageData;
2003 -        bool hasAlpha = false;
2004 -        bool hasMask = false;
2005 -
2006 +        uLongf target=1024*1024*1024;
2007 +        bool uns=false;
2008 +        bool dct = false;
2009 +        
2010 +        d = (colorMode == QPrinter::GrayScale) ? 8 : 32;
2011 +               
2012          if (QImageWriter::supportedImageFormats().contains("jpeg") && colorMode != QPrinter::GrayScale) {
2013 -            QBuffer buffer(&imageData);
2014 +            QByteArray imageData2;
2015 +            
2016 +            QBuffer buffer(&imageData2);
2017              QImageWriter writer(&buffer, "jpeg");
2018 -            writer.setQuality(94);
2019 +            writer.setQuality(imageQuality);
2020              writer.write(image);
2021 -            dct = true;
2022 -
2023 -            if (format != QImage::Format_RGB32) {
2024 -                softMaskData.resize(w * h);
2025 -                uchar *sdata = (uchar *)softMaskData.data();
2026 -                for (int y = 0; y < h; ++y) {
2027 -                    const QRgb *rgb = (const QRgb *)image.scanLine(y);
2028 -                    for (int x = 0; x < w; ++x) {
2029 -                        uchar alpha = qAlpha(*rgb);
2030 -                        *sdata++ = alpha;
2031 -                        hasMask |= (alpha < 255);
2032 -                        hasAlpha |= (alpha != 0 && alpha != 255);
2033 -                        ++rgb;
2034 -                    }
2035 -                }
2036 +            
2037 +            if ((uLongf)imageData2.size() < target) {
2038 +                imageData=imageData2;
2039 +                target = imageData2.size();
2040 +                dct = true;
2041 +                uns=false;
2042              }
2043 -        } else {
2044 -            imageData.resize(colorMode == QPrinter::GrayScale ? w * h : 3 * w * h);
2045 -            uchar *data = (uchar *)imageData.data();
2046 +        }
2047 +
2048 +        if (noneScaled && noneScaled->rect() != image.rect()) {
2049 +            QByteArray imageData2;
2050 +            convertImage(*noneScaled, imageData2);
2051 +            uLongf len = imageData2.size();
2052 +            uLongf destLen = len + len/100 + 13; // zlib requirement
2053 +            Bytef* dest = new Bytef[destLen];
2054 +            if (Z_OK == ::compress(dest, &destLen, (const Bytef*) imageData2.data(), (uLongf)len) &&
2055 +                (uLongf)destLen < target) {
2056 +                imageData=imageData2;
2057 +                target=destLen;
2058 +                dct=false;
2059 +                uns=true;
2060 +            }
2061 +            delete[] dest;
2062 +        }
2063 +        
2064 +        {
2065 +            QByteArray imageData2;
2066 +            convertImage(image, imageData2);
2067 +            uLongf len = imageData2.size();
2068 +            uLongf destLen = len + len/100 + 13; // zlib requirement
2069 +            Bytef* dest = new Bytef[destLen];
2070 +            if (Z_OK == ::compress(dest, &destLen, (const Bytef*) imageData2.data(), (uLongf)len) &&
2071 +                (uLongf)destLen < target) {
2072 +                imageData=imageData2;
2073 +                target=destLen;
2074 +                dct=false;
2075 +                uns=false;
2076 +            }
2077 +            delete[] dest;
2078 +        }
2079 +
2080 +
2081 +        if (colorMode != QPrinter::GrayScale && noneScaled != 0 && data != 0) {
2082 +         jpg_header_reader header;
2083 +         if (header.read(data)) {
2084 +           d = header.components == 3?32:8;
2085 +            imageData = *data;
2086 +            target=data->size();
2087 +            dct=true;
2088 +            uns=true;
2089 +         }
2090 +        }
2091 +
2092 +        if (uns) {
2093 +            w = noneScaled->width();
2094 +            h = noneScaled->height();
2095 +        }
2096 +        if (useScaled) *useScaled = (uns?false:true);
2097 +        QByteArray softMaskData;
2098 +        bool hasAlpha = false;
2099 +        bool hasMask = false;
2100 +        
2101 +        if (format != QImage::Format_RGB32) {
2102              softMaskData.resize(w * h);
2103              uchar *sdata = (uchar *)softMaskData.data();
2104              for (int y = 0; y < h; ++y) {
2105 -                const QRgb *rgb = (const QRgb *)image.scanLine(y);
2106 -                if (colorMode == QPrinter::GrayScale) {
2107 -                    for (int x = 0; x < w; ++x) {
2108 -                        *(data++) = qGray(*rgb);
2109 -                        uchar alpha = qAlpha(*rgb);
2110 -                        *sdata++ = alpha;
2111 -                        hasMask |= (alpha < 255);
2112 -                        hasAlpha |= (alpha != 0 && alpha != 255);
2113 -                        ++rgb;
2114 -                    }
2115 -                } else {
2116 -                    for (int x = 0; x < w; ++x) {
2117 -                        *(data++) = qRed(*rgb);
2118 -                        *(data++) = qGreen(*rgb);
2119 -                        *(data++) = qBlue(*rgb);
2120 -                        uchar alpha = qAlpha(*rgb);
2121 -                        *sdata++ = alpha;
2122 -                        hasMask |= (alpha < 255);
2123 -                        hasAlpha |= (alpha != 0 && alpha != 255);
2124 -                        ++rgb;
2125 -                    }
2126 +                const QRgb *rgb = (const QRgb *)(uns?noneScaled->scanLine(y):image.scanLine(y));
2127 +                for (int x = 0; x < w; ++x) {
2128 +                    uchar alpha = qAlpha(*rgb);
2129 +                    *sdata++ = alpha;
2130 +                    hasMask |= (alpha < 255);
2131 +                    hasAlpha |= (alpha != 0 && alpha != 255);
2132 +                    ++rgb;
2133                  }
2134              }
2135 -            if (format == QImage::Format_RGB32)
2136 -                hasAlpha = hasMask = false;
2137          }
2138 +        
2139          int maskObject = 0;
2140          int softMaskObject = 0;
2141          if (hasAlpha) {
2142 @@ -644,7 +988,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
2143              }
2144              maskObject = writeImage(mask, w, h, 1, 0, 0);
2145          }
2146 -        object = writeImage(imageData, w, h, colorMode == QPrinter::GrayScale ? 8 : 32,
2147 +        object = writeImage(imageData, w, h, d,
2148                              maskObject, softMaskObject, dct);
2149      }
2150      imageCache.insert(serial_no, object);
2151 @@ -754,7 +1098,7 @@ void QPdfEnginePrivate::xprintf(const char* fmt, ...)
2152  int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
2153  {
2154  #ifndef QT_NO_COMPRESS
2155 -    if (do_compress) {
2156 +    if (doCompress) {
2157          int size = QPdfPage::chunkSize();
2158          int sum = 0;
2159          ::z_stream zStruct;
2160 @@ -828,7 +1172,7 @@ int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
2161  int QPdfEnginePrivate::writeCompressed(const char *src, int len)
2162  {
2163  #ifndef QT_NO_COMPRESS
2164 -    if(do_compress) {
2165 +    if(doCompress) {
2166          uLongf destLen = len + len/100 + 13; // zlib requirement
2167          Bytef* dest = new Bytef[destLen];
2168          if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) {
2169 @@ -881,7 +1225,7 @@ int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height,
2170          write(data);
2171          len = data.length();
2172      } else {
2173 -        if (do_compress)
2174 +        if (doCompress)
2175              xprintf("/Filter /FlateDecode\n>>\nstream\n");
2176          else
2177              xprintf(">>\nstream\n");
2178 @@ -904,14 +1248,9 @@ void QPdfEnginePrivate::writeHeader()
2179  
2180      writeInfo();
2181  
2182 -    catalog = addXrefEntry(-1);
2183      pageRoot = requestObject();
2184 -    xprintf("<<\n"
2185 -            "/Type /Catalog\n"
2186 -            "/Pages %d 0 R\n"
2187 -            ">>\n"
2188 -            "endobj\n", pageRoot);
2189 -
2190 +    
2191 +    formFieldList = -1;
2192      // graphics state
2193      graphicsState = addXrefEntry(-1);
2194      xprintf("<<\n"
2195 @@ -939,17 +1278,26 @@ void QPdfEnginePrivate::writeInfo()
2196      xprintf("\n/Creator ");
2197      printString(creator);
2198      xprintf("\n/Producer ");
2199 -    printString(QString::fromLatin1("Qt " QT_VERSION_STR " (C) 2011 Nokia Corporation and/or its subsidiary(-ies)"));
2200 -    QDateTime now = QDateTime::currentDateTime().toUTC();
2201 +    printString(QString::fromLatin1("wkhtmltopdf"));
2202 +    QDateTime now = QDateTime::currentDateTime();
2203      QTime t = now.time();
2204      QDate d = now.date();
2205 -    xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n",
2206 +    xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d",
2207              d.year(),
2208              d.month(),
2209              d.day(),
2210              t.hour(),
2211              t.minute(),
2212              t.second());
2213 +    QDateTime fake=now;
2214 +    fake.setTimeSpec(Qt::UTC);
2215 +    int offset = now.secsTo(fake);
2216 +    if (offset == 0)
2217 +        xprintf("Z)\n");
2218 +    else if (offset < 0)
2219 +        xprintf("-%02d'%02d')\n", (-offset)/60/60 , ((-offset)/60) % 60);
2220 +    else if (offset > 0)
2221 +        xprintf("+%02d'%02d')\n", offset/60/60 , (offset/60) % 60);
2222      xprintf(">>\n"
2223              "endobj\n");
2224  }
2225 @@ -1035,7 +1383,7 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
2226          s << "<<\n"
2227              "/Length1 " << fontData.size() << "\n"
2228              "/Length " << length_object << "0 R\n";
2229 -        if (do_compress)
2230 +        if (doCompress)
2231              s << "/Filter /FlateDecode\n";
2232          s << ">>\n"
2233              "stream\n";
2234 @@ -1097,6 +1445,101 @@ void QPdfEnginePrivate::writeFonts()
2235      fonts.clear();
2236  }
2237  
2238 +
2239 +void QPdfEngine::addHyperlink(const QRectF &r, const QUrl &url)
2240 +{
2241 +    Q_D(QPdfEngine);
2242 +    char buf[256];
2243 +    QRectF rr = d->pageMatrix().mapRect(r);
2244 +    uint annot = d->addXrefEntry(-1);
2245 +    QByteArray urlascii = url.toString().toLatin1();
2246 +    int len = urlascii.size();
2247 +    char *url_esc = new char[len * 2 + 1];
2248 +    const char * urldata = urlascii.constData();
2249 +    int k = 0;
2250 +    for (int j = 0; j < len; j++, k++){
2251 +        if (urldata[j] == '(' ||
2252 +            urldata[j] == ')' ||
2253 +            urldata[j] == '\\'){
2254 +            url_esc[k] = '\\';
2255 +            k++;
2256 +        }
2257 +        url_esc[k] = urldata[j];
2258 +    }
2259 +    url_esc[k] = 0;
2260 +    d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [");
2261 +    d->xprintf("%s ", qt_real_to_string(rr.left(),buf));
2262 +    d->xprintf("%s ", qt_real_to_string(rr.top(),buf));
2263 +    d->xprintf("%s ", qt_real_to_string(rr.right(),buf));
2264 +    d->xprintf("%s", qt_real_to_string(rr.bottom(),buf));
2265 +    d->xprintf("]\n/Border [0 0 0]\n/A <<\n");
2266 +    d->xprintf("/Type /Action\n/S /URI\n/URI (%s)\n", url_esc);
2267 +    d->xprintf(">>\n>>\n");
2268 +    d->xprintf("endobj\n");
2269 +    d->currentPage->annotations.append(annot);
2270 +    delete[] url_esc;
2271 +}
2272 +
2273 +void QPdfEngine::addLink(const QRectF &r, const QString &anchor)
2274 +{
2275 +    Q_D(QPdfEngine);
2276 +    char buf[256];
2277 +    QRectF rr = d->pageMatrix().mapRect(r);
2278 +    uint annot = d->addXrefEntry(-1);
2279 +    d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [");
2280 +    d->xprintf("%s ", qt_real_to_string(rr.left(),buf));
2281 +    d->xprintf("%s ", qt_real_to_string(rr.top(),buf));
2282 +    d->xprintf("%s ", qt_real_to_string(rr.right(),buf));
2283 +    d->xprintf("%s", qt_real_to_string(rr.bottom(),buf));
2284 +    d->xprintf("]\n/Border [0 0 0]\n/Dest ");
2285 +    d->printAnchor(anchor);
2286 +    d->xprintf("\n>>\n");
2287 +    d->xprintf("endobj\n");
2288 +    d->currentPage->annotations.append(annot);
2289 +}
2290 +
2291 +void QPdfEngine::addAnchor(const QRectF &r, const QString &name)
2292 +{
2293 +    Q_D(QPdfEngine);
2294 +    char buf[256];
2295 +    QRectF rr = d->pageMatrix().mapRect(r);
2296 +    uint anchor = d->addXrefEntry(-1);
2297 +    d->xprintf("[%d /XYZ %s \n",
2298 +               d->pages.size() - 1,
2299 +               qt_real_to_string(rr.left(), buf));
2300 +    d->xprintf("%s 0]\n",
2301 +               qt_real_to_string(rr.bottom(), buf));
2302 +    d->xprintf("endobj\n");
2303 +    d->anchors[name] = anchor;
2304 +}
2305 +
2306 +void QPdfEngine::beginSectionOutline(const QString &text, const QString &anchor)
2307 +{
2308 +    Q_D(QPdfEngine);
2309 +    if (d->outlineCurrent == NULL) {
2310 +        if (d->outlineRoot)
2311 +            delete d->outlineRoot;
2312 +        d->outlineCurrent = d->outlineRoot = new QPdfEnginePrivate::OutlineItem(QString(), QString());
2313 +    }
2314 +    
2315 +    QPdfEnginePrivate::OutlineItem *i = new QPdfEnginePrivate::OutlineItem(text, anchor);
2316 +    i->parent = d->outlineCurrent;
2317 +    i->prev = d->outlineCurrent->lastChild;
2318 +    if (d->outlineCurrent->firstChild)
2319 +        d->outlineCurrent->lastChild->next = i;
2320 +    else
2321 +        d->outlineCurrent->firstChild = i;
2322 +    d->outlineCurrent->lastChild = i;
2323 +    d->outlineCurrent = i;
2324 +}
2325 +
2326 +void QPdfEngine::endSectionOutline()
2327 +{
2328 +    Q_D(QPdfEngine);
2329 +    if (d->outlineCurrent)
2330 +        d->outlineCurrent = d->outlineCurrent->parent;
2331 +}
2332 +
2333  void QPdfEnginePrivate::writePage()
2334  {
2335      if (pages.empty())
2336 @@ -1167,7 +1610,7 @@ void QPdfEnginePrivate::writePage()
2337      addXrefEntry(pageStream);
2338      xprintf("<<\n"
2339              "/Length %d 0 R\n", pageStreamLength); // object number for stream length object
2340 -    if (do_compress)
2341 +    if (doCompress)
2342          xprintf("/Filter /FlateDecode\n");
2343  
2344      xprintf(">>\n");
2345 diff --git a/src/gui/painting/qprintengine_pdf_p.h b/src/gui/painting/qprintengine_pdf_p.h
2346 index 9b9185a..1586caa 100644
2347 --- a/src/gui/painting/qprintengine_pdf_p.h
2348 +++ b/src/gui/painting/qprintengine_pdf_p.h
2349 @@ -92,7 +92,12 @@ public:
2350      // reimplementations QPaintEngine
2351      bool begin(QPaintDevice *pdev);
2352      bool end();
2353 -    void drawPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr);
2354 +
2355 +    void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr, const QByteArray * data=0);
2356 +    void drawPixmap(const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr) {
2357 +        drawPixmap(rectangle, pixmap, sr, 0);
2358 +    }
2359 +
2360      void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
2361                     Qt::ImageConversionFlags flags = Qt::AutoColor);
2362      void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point);
2363 @@ -108,12 +113,23 @@ public:
2364  
2365      void setBrush();
2366  
2367 +    virtual void addHyperlink(const QRectF &r, const QUrl &url);
2368 +    virtual void addAnchor(const QRectF &r, const QString &name);
2369 +    virtual void addLink(const QRectF &r, const QString &anchor);
2370 +    virtual void addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength);
2371 +    virtual void addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly);
2372 +
2373      // ### unused, should have something for this in QPrintEngine
2374      void setAuthor(const QString &author);
2375      QString author() const;
2376  
2377      void setDevice(QIODevice* dev);
2378  
2379 +    void beginSectionOutline(const QString &text, const QString &anchor);
2380 +    void endSectionOutline();
2381 +
2382 +    void setProperty(PrintEnginePropertyKey key, const QVariant &value);
2383 +    QVariant property(PrintEnginePropertyKey key) const;
2384  private:
2385      Q_DISABLE_COPY(QPdfEngine)
2386  
2387 @@ -124,6 +140,35 @@ class QPdfEnginePrivate : public QPdfBaseEnginePrivate
2388  {
2389      Q_DECLARE_PUBLIC(QPdfEngine)
2390  public:
2391 +  
2392 +    class OutlineItem {
2393 +    public:
2394 +        OutlineItem *parent;
2395 +        OutlineItem *next;
2396 +        OutlineItem *prev;
2397 +        OutlineItem *firstChild;
2398 +        OutlineItem *lastChild;
2399 +        uint obj;
2400 +        QString text;
2401 +        QString anchor;
2402 +        
2403 +        OutlineItem(const QString &t, const QString &a): 
2404 +            parent(NULL), next(NULL), prev(NULL), firstChild(NULL), lastChild(NULL),
2405 +            obj(0), text(t), anchor(a) {}
2406 +        ~OutlineItem() {
2407 +            OutlineItem *i = firstChild;
2408 +            while(i != NULL) { 
2409 +                OutlineItem *n = i->next;
2410 +                delete i;
2411 +                i=n;
2412 +            }
2413 +        }
2414 +    };
2415 +    
2416 +    OutlineItem *outlineRoot;
2417 +    OutlineItem *outlineCurrent;
2418 +    void writeOutlineChildren(OutlineItem *node);
2419 +    
2420      QPdfEnginePrivate(QPrinter::PrinterMode m);
2421      ~QPdfEnginePrivate();
2422  
2423 @@ -141,7 +186,9 @@ public:
2424      void writeHeader();
2425      void writeTail();
2426  
2427 -    int addImage(const QImage &image, bool *bitmap, qint64 serial_no);
2428 +    void convertImage(const QImage & image, QByteArray & imageData);
2429 +
2430 +    int addImage(const QImage &image, bool *bitmap, qint64 serial_no, const QImage * noneScaled=0, const QByteArray * data=0, bool * useScaled=0);
2431      int addConstantAlphaObject(int brushAlpha, int penAlpha = 255);
2432      int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject);
2433  
2434 @@ -161,16 +208,25 @@ private:
2435      void writeFonts();
2436      void embedFont(QFontSubset *font);
2437  
2438 +    int formFieldList;
2439 +    QVector<uint> formFields;
2440      QVector<int> xrefPositions;
2441      QDataStream* stream;
2442      int streampos;
2443  
2444 +    bool doCompress;
2445 +    int imageDPI;
2446 +    int imageQuality;
2447 +
2448      int writeImage(const QByteArray &data, int width, int height, int depth,
2449                     int maskObject, int softMaskObject, bool dct = false);
2450      void writePage();
2451  
2452      int addXrefEntry(int object, bool printostr = true);
2453 +
2454      void printString(const QString &string);
2455 +    void printAnchor(const QString &name);
2456 +    
2457      void xprintf(const char* fmt, ...);
2458      inline void write(const QByteArray &data) {
2459          stream->writeRawData(data.constData(), data.size());
2460 @@ -183,6 +239,8 @@ private:
2461  
2462      // various PDF objects
2463      int pageRoot, catalog, info, graphicsState, patternColorSpace;
2464 +    QVector<uint> dests;
2465 +    QHash<QString, uint> anchors;
2466      QVector<uint> pages;
2467      QHash<qint64, uint> imageCache;
2468      QHash<QPair<uint, uint>, uint > alphaCache;
2469 diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
2470 index 134447c..2c58619 100644
2471 --- a/src/gui/painting/qprinter.cpp
2472 +++ b/src/gui/painting/qprinter.cpp
2473 @@ -933,6 +933,39 @@ void QPrinter::setOutputFileName(const QString &fileName)
2474      d->addToManualSetList(QPrintEngine::PPK_OutputFileName);
2475  }
2476  
2477 +/*!
2478 +    Add a section to the document outline. All following sections will be added
2479 +    to as subsections to this section, until endSectionOutline() has been called.
2480 +
2481 +    \a name is the name of the added section. \a anchor is the name of an anchor
2482 +    indicating the beginning of the section.  This anchor must be added by calling
2483 +    QPainter::addAnchor().
2484 +
2485 +    Note that for output formats not supporting outlines, currently all other then PDF,
2486 +    this call has no effect.
2487 +
2488 +    \sa endSectionOutline() QPainter::addAnchor() 
2489 +
2490 +    \since 4.7
2491 +*/
2492 +void QPrinter::beginSectionOutline(const QString &name, const QString &anchor)
2493 +{
2494 +    Q_D(QPrinter);
2495 +    d->printEngine->beginSectionOutline(name, anchor);
2496 +}
2497 +
2498 +/*!
2499 +    End the current section.
2500 +
2501 +    \sa beginSectionOutline()
2502 +
2503 +    \since 4.7
2504 +*/
2505 +void QPrinter::endSectionOutline() 
2506 +{
2507 +    Q_D(QPrinter);
2508 +    d->printEngine->endSectionOutline();
2509 +}
2510  
2511  /*!
2512    Returns the name of the program that sends the print output to the
2513 diff --git a/src/gui/painting/qprinter.h b/src/gui/painting/qprinter.h
2514 index f133a5d..46baf8c 100644
2515 --- a/src/gui/painting/qprinter.h
2516 +++ b/src/gui/painting/qprinter.h
2517 @@ -147,6 +147,9 @@ public:
2518      enum PrinterOption { PrintToFile, PrintSelection, PrintPageRange };
2519  #endif // QT3_SUPPORT
2520  
2521 +    void beginSectionOutline(const QString &text, const QString &anchor);
2522 +    void endSectionOutline();
2523 +
2524      void setOutputFormat(OutputFormat format);
2525      OutputFormat outputFormat() const;
2526  
2527 diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
2528 index 52ce9a7..eddbb80 100644
2529 --- a/src/gui/styles/qstyle.cpp
2530 +++ b/src/gui/styles/qstyle.cpp
2531 @@ -47,6 +47,7 @@
2532  #include "qpixmapcache.h"
2533  #include "qstyleoption.h"
2534  #include "private/qstyle_p.h"
2535 +#include "private/qapplication_p.h"
2536  #ifndef QT_NO_DEBUG
2537  #include "qdebug.h"
2538  #endif
2539 @@ -2229,7 +2230,7 @@ QPalette QStyle::standardPalette() const
2540  {
2541  #ifdef Q_WS_X11
2542      QColor background;
2543 -    if (QX11Info::appDepth() > 8)
2544 +    if (!qt_is_gui_used || QX11Info::appDepth() > 8)
2545          background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey
2546      else
2547          background = QColor(192, 192, 192);
2548 diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp
2549 index f512992..9ee9096 100644
2550 --- a/src/svg/qsvggenerator.cpp
2551 +++ b/src/svg/qsvggenerator.cpp
2552 @@ -103,6 +103,7 @@ public:
2553  
2554          afterFirstUpdate = false;
2555          numGradients = 0;
2556 +        clip = false;
2557      }
2558  
2559      QSize size;
2560 @@ -129,6 +130,9 @@ public:
2561  
2562      QString currentGradientName;
2563      int numGradients;
2564 +    QString stateString;
2565 +    QString oldStateString;
2566 +    bool clip;
2567  
2568      struct _attributes {
2569          QString document_title;
2570 @@ -141,6 +145,18 @@ public:
2571          QString dashPattern, dashOffset;
2572          QString fill, fillOpacity;
2573      } attributes;
2574 +
2575 +    void emitState() {
2576 +        if (stateString == oldStateString) return;
2577 +
2578 +        // close old state and start a new one...
2579 +        if (afterFirstUpdate)
2580 +            *stream << "</g>\n\n";
2581 +        
2582 +        *stream << stateString;
2583 +        afterFirstUpdate = true;
2584 +        oldStateString = stateString;
2585 +    }
2586  };
2587  
2588  static inline QPaintEngine::PaintEngineFeatures svgEngineFeatures()
2589 @@ -322,7 +338,7 @@ public:
2590      }
2591  
2592  
2593 -    void qpenToSvg(const QPen &spen)
2594 +    void qpenToSvg(const QPen &spen, QTextStream & s)
2595      {
2596          QString width;
2597  
2598 @@ -330,7 +346,7 @@ public:
2599  
2600          switch (spen.style()) {
2601          case Qt::NoPen:
2602 -            stream() << QLatin1String("stroke=\"none\" ");
2603 +            s << QLatin1String("stroke=\"none\" ");
2604  
2605              d_func()->attributes.stroke = QLatin1String("none");
2606              d_func()->attributes.strokeOpacity = QString();
2607 @@ -344,8 +360,8 @@ public:
2608              d_func()->attributes.stroke = color;
2609              d_func()->attributes.strokeOpacity = colorOpacity;
2610  
2611 -            stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
2612 -            stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
2613 +            s << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
2614 +            s << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
2615          }
2616              break;
2617          case Qt::DashLine:
2618 @@ -368,10 +384,10 @@ public:
2619              d_func()->attributes.dashPattern = dashPattern;
2620              d_func()->attributes.dashOffset = dashOffset;
2621  
2622 -            stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
2623 -            stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
2624 -            stream() << QLatin1String("stroke-dasharray=\"")<<dashPattern<< QLatin1String("\" ");
2625 -            stream() << QLatin1String("stroke-dashoffset=\"")<<dashOffset<< QLatin1String("\" ");
2626 +            s << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");
2627 +            s << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");
2628 +            s << QLatin1String("stroke-dasharray=\"")<<dashPattern<< QLatin1String("\" ");
2629 +            s << QLatin1String("stroke-dashoffset=\"")<<dashOffset<< QLatin1String("\" ");
2630              break;
2631          }
2632          default:
2633 @@ -380,50 +396,50 @@ public:
2634          }
2635  
2636          if (spen.widthF() == 0)
2637 -            stream() <<"stroke-width=\"1\" ";
2638 +            s <<"stroke-width=\"1\" ";
2639          else
2640 -            stream() <<"stroke-width=\"" << spen.widthF() << "\" ";
2641 +            s <<"stroke-width=\"" << spen.widthF() << "\" ";
2642  
2643          switch (spen.capStyle()) {
2644          case Qt::FlatCap:
2645 -            stream() << "stroke-linecap=\"butt\" ";
2646 +            s << "stroke-linecap=\"butt\" ";
2647              break;
2648          case Qt::SquareCap:
2649 -            stream() << "stroke-linecap=\"square\" ";
2650 +            s << "stroke-linecap=\"square\" ";
2651              break;
2652          case Qt::RoundCap:
2653 -            stream() << "stroke-linecap=\"round\" ";
2654 +            s << "stroke-linecap=\"round\" ";
2655              break;
2656          default:
2657              qWarning("Unhandled cap style");
2658          }
2659          switch (spen.joinStyle()) {
2660          case Qt::MiterJoin:
2661 -            stream() << "stroke-linejoin=\"miter\" "
2662 +            s << "stroke-linejoin=\"miter\" "
2663                          "stroke-miterlimit=\""<<spen.miterLimit()<<"\" ";
2664              break;
2665          case Qt::BevelJoin:
2666 -            stream() << "stroke-linejoin=\"bevel\" ";
2667 +            s << "stroke-linejoin=\"bevel\" ";
2668              break;
2669          case Qt::RoundJoin:
2670 -            stream() << "stroke-linejoin=\"round\" ";
2671 +            s << "stroke-linejoin=\"round\" ";
2672              break;
2673          case Qt::SvgMiterJoin:
2674 -            stream() << "stroke-linejoin=\"miter\" "
2675 +            s << "stroke-linejoin=\"miter\" "
2676                          "stroke-miterlimit=\""<<spen.miterLimit()<<"\" ";
2677              break;
2678          default:
2679              qWarning("Unhandled join style");
2680          }
2681      }
2682 -    void qbrushToSvg(const QBrush &sbrush)
2683 +    void qbrushToSvg(const QBrush &sbrush, QTextStream & s)
2684      {
2685          d_func()->brush = sbrush;
2686          switch (sbrush.style()) {
2687          case Qt::SolidPattern: {
2688              QString color, colorOpacity;
2689              translate_color(sbrush.color(), &color, &colorOpacity);
2690 -            stream() << "fill=\"" << color << "\" "
2691 +            s << "fill=\"" << color << "\" "
2692                          "fill-opacity=\""
2693                       << colorOpacity << "\" ";
2694              d_func()->attributes.fill = color;
2695 @@ -434,22 +450,22 @@ public:
2696              saveLinearGradientBrush(sbrush.gradient());
2697              d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);
2698              d_func()->attributes.fillOpacity = QString();
2699 -            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
2700 +            s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
2701              break;
2702          case Qt::RadialGradientPattern:
2703              saveRadialGradientBrush(sbrush.gradient());
2704              d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);
2705              d_func()->attributes.fillOpacity = QString();
2706 -            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
2707 +            s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
2708              break;
2709          case Qt::ConicalGradientPattern:
2710              saveConicalGradientBrush(sbrush.gradient());
2711              d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);
2712              d_func()->attributes.fillOpacity = QString();
2713 -            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
2714 +            s << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");
2715              break;
2716          case Qt::NoBrush:
2717 -            stream() << QLatin1String("fill=\"none\" ");
2718 +            s << QLatin1String("fill=\"none\" ");
2719              d_func()->attributes.fill = QLatin1String("none");
2720              d_func()->attributes.fillOpacity = QString();
2721              return;
2722 @@ -458,7 +474,7 @@ public:
2723             break;
2724          }
2725      }
2726 -    void qfontToSvg(const QFont &sfont)
2727 +    void qfontToSvg(const QFont &sfont, QTextStream & s)
2728      {
2729          Q_D(QSvgPaintEngine);
2730  
2731 @@ -488,12 +504,23 @@ public:
2732          d->attributes.font_family = d->font.family();
2733          d->attributes.font_style = d->font.italic() ? QLatin1String("italic") : QLatin1String("normal");
2734  
2735 -        *d->stream << "font-family=\"" << d->attributes.font_family << "\" "
2736 -                      "font-size=\"" << d->attributes.font_size << "\" "
2737 -                      "font-weight=\"" << d->attributes.font_weight << "\" "
2738 -                      "font-style=\"" << d->attributes.font_style << "\" "
2739 -                   << endl;
2740 +        s << "font-family=\"" << d->attributes.font_family << "\" "
2741 +             "font-size=\"" << d->attributes.font_size << "\" "
2742 +             "font-weight=\"" << d->attributes.font_weight << "\" "
2743 +             "font-style=\"" << d->attributes.font_style << "\" "
2744 +             << endl;
2745 +    }
2746 +
2747 +    void setViewBoxClip(bool clip) {
2748 +        Q_D(QSvgPaintEngine);
2749 +        d->clip = clip;
2750      }
2751 +    
2752 +    bool viewBoxClip() const {
2753 +        Q_D(const QSvgPaintEngine);
2754 +        return d->clip;
2755 +    }
2756 +
2757  };
2758  
2759  class QSvgGeneratorPrivate
2760 @@ -808,6 +835,27 @@ int QSvgGenerator::metric(QPaintDevice::PaintDeviceMetric metric) const
2761      return 0;
2762  }
2763  
2764 +/*!
2765 +    \property QSvgGenerator::resolution
2766 +    \brief do not draw objects outside the viewBox
2767 +    \since 4.7
2768 +
2769 +    When specified objects drawn compleatly outsite the viewBox
2770 +    are not include in the output SVG.
2771 +
2772 +    \sa viewBox
2773 +*/
2774 +
2775 +bool QSvgGenerator::viewBoxClip() const {
2776 +    Q_D(const QSvgGenerator);
2777 +    return d->engine->viewBoxClip();
2778 +}
2779 +
2780 +void QSvgGenerator::setViewBoxClip(bool clip) {
2781 +    Q_D(QSvgGenerator);
2782 +    d->engine->setViewBoxClip(clip);
2783 +}
2784 +
2785  /*****************************************************************************
2786   * class QSvgPaintEngine
2787   */
2788 @@ -908,10 +956,13 @@ void QSvgPaintEngine::drawImage(const QRectF &r, const QImage &image,
2789                                  const QRectF &sr,
2790                                  Qt::ImageConversionFlag flags)
2791  {
2792 -    //Q_D(QSvgPaintEngine);
2793 +    Q_D(QSvgPaintEngine);
2794  
2795      Q_UNUSED(sr);
2796      Q_UNUSED(flags);
2797 +    if (d->clip && !d->matrix.mapRect(r).intersects(d->viewBox)) return;
2798 +    d->emitState();
2799 +
2800      stream() << "<image ";
2801      stream() << "x=\""<<r.x()<<"\" "
2802                  "y=\""<<r.y()<<"\" "
2803 @@ -932,53 +983,35 @@ void QSvgPaintEngine::drawImage(const QRectF &r, const QImage &image,
2804  void QSvgPaintEngine::updateState(const QPaintEngineState &state)
2805  {
2806      Q_D(QSvgPaintEngine);
2807 -    QPaintEngine::DirtyFlags flags = state.state();
2808 -
2809 -    // always stream full gstate, which is not required, but...
2810 -    flags |= QPaintEngine::AllDirty;
2811 -
2812 -    // close old state and start a new one...
2813 -    if (d->afterFirstUpdate)
2814 -        *d->stream << "</g>\n\n";
2815 -
2816 -    *d->stream << "<g ";
2817  
2818 -    if (flags & QPaintEngine::DirtyBrush) {
2819 -        qbrushToSvg(state.brush());
2820 -    }
2821 -
2822 -    if (flags & QPaintEngine::DirtyPen) {
2823 -        qpenToSvg(state.pen());
2824 -    }
2825 -
2826 -    if (flags & QPaintEngine::DirtyTransform) {
2827 -        d->matrix = state.matrix();
2828 -        *d->stream << "transform=\"matrix(" << d->matrix.m11() << ','
2829 -                   << d->matrix.m12() << ','
2830 -                   << d->matrix.m21() << ',' << d->matrix.m22() << ','
2831 -                   << d->matrix.dx() << ',' << d->matrix.dy()
2832 -                   << ")\""
2833 -                   << endl;
2834 -    }
2835 -
2836 -    if (flags & QPaintEngine::DirtyFont) {
2837 -        qfontToSvg(state.font());
2838 -    }
2839 -
2840 -    if (flags & QPaintEngine::DirtyOpacity) {
2841 -        if (!qFuzzyIsNull(state.opacity() - 1))
2842 -            stream() << "opacity=\""<<state.opacity()<<"\" ";
2843 -    }
2844 -
2845 -    *d->stream << '>' << endl;
2846 -
2847 -    d->afterFirstUpdate = true;
2848 +    d->stateString="";
2849 +    QTextStream stateStream(&d->stateString);
2850 +    stateStream << "<g ";
2851 +    qbrushToSvg(state.brush(), stateStream);
2852 +    qpenToSvg(state.pen(), stateStream);
2853 +    
2854 +    d->matrix = state.matrix();
2855 +    stateStream << "transform=\"matrix(" << d->matrix.m11() << ','
2856 +                << d->matrix.m12() << ','
2857 +                << d->matrix.m21() << ',' << d->matrix.m22() << ','
2858 +                << d->matrix.dx() << ',' << d->matrix.dy()
2859 +                << ")\""
2860 +                << endl;
2861 +    qfontToSvg(state.font(), stateStream);
2862 +    
2863 +    if (!qFuzzyIsNull(state.opacity() - 1))
2864 +        stateStream << "opacity=\""<<state.opacity()<<"\" ";
2865 +    
2866 +    stateStream << '>' << endl;
2867  }
2868  
2869  void QSvgPaintEngine::drawPath(const QPainterPath &p)
2870  {
2871      Q_D(QSvgPaintEngine);
2872  
2873 +    if (d->clip && !d->matrix.mapRect(p.boundingRect()).intersects(d->viewBox)) return;
2874 +    d->emitState();
2875 +    
2876      *d->stream << "<path vector-effect=\""
2877                 << (state->pen().isCosmetic() ? "non-scaling-stroke" : "none")
2878                 << "\" fill-rule=\""
2879 @@ -1024,12 +1057,15 @@ void QSvgPaintEngine::drawPolygon(const QPointF *points, int pointCount,
2880  {
2881      Q_ASSERT(pointCount >= 2);
2882  
2883 -    //Q_D(QSvgPaintEngine);
2884 +    Q_D(QSvgPaintEngine);
2885  
2886      QPainterPath path(points[0]);
2887      for (int i=1; i<pointCount; ++i)
2888          path.lineTo(points[i]);
2889  
2890 +    if (d->clip && !d->matrix.mapRect(path.boundingRect()).intersects(d->viewBox)) return;
2891 +    d->emitState();
2892 +
2893      if (mode == PolylineMode) {
2894          stream() << "<polyline fill=\"none\" vector-effect=\""
2895                   << (state->pen().isCosmetic() ? "non-scaling-stroke" : "none")
2896 @@ -1051,6 +1087,12 @@ void QSvgPaintEngine::drawTextItem(const QPointF &pt, const QTextItem &textItem)
2897      if (d->pen.style() == Qt::NoPen)
2898          return;
2899  
2900 +    if (d->clip) {
2901 +        QRectF b=painter()->boundingRect( QRectF(pt, QSize()) , Qt::AlignLeft, textItem.text());
2902 +        if (!d->matrix.mapRect(b).intersects(d->viewBox)) return;
2903 +    }
2904 +    d->emitState();
2905 +
2906      const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
2907      QString s = QString::fromRawData(ti.chars, ti.num_chars);
2908  
2909 @@ -1060,7 +1102,7 @@ void QSvgPaintEngine::drawTextItem(const QPointF &pt, const QTextItem &textItem)
2910                    "stroke=\"none\" "
2911                    "xml:space=\"preserve\" "
2912                    "x=\"" << pt.x() << "\" y=\"" << pt.y() << "\" ";
2913 -    qfontToSvg(textItem.font());
2914 +    qfontToSvg(textItem.font(), *d->stream);
2915      *d->stream << " >"
2916                 << Qt::escape(s)
2917                 << "</text>"
2918 diff --git a/src/svg/qsvggenerator.h b/src/svg/qsvggenerator.h
2919 index 7981f28..2197ad8 100644
2920 --- a/src/svg/qsvggenerator.h
2921 +++ b/src/svg/qsvggenerator.h
2922 @@ -96,6 +96,9 @@ public:
2923  
2924      void setResolution(int dpi);
2925      int resolution() const;
2926 +
2927 +    void setViewBoxClip(bool clip);
2928 +    bool viewBoxClip() const;
2929  protected:
2930      QPaintEngine *paintEngine() const;
2931      int metric(QPaintDevice::PaintDeviceMetric metric) const;
2932 diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
2933 index 4b8000d..6d52696 100644
2934 --- a/tools/configure/configureapp.cpp
2935 +++ b/tools/configure/configureapp.cpp
2936 @@ -2381,9 +2381,9 @@ bool Configure::checkAvailability(const QString &part)
2937          available = qmakeSpec == "win32-msvc2005" || qmakeSpec == "win32-msvc2008" ||
2938                  qmakeSpec == "win32-msvc2010" || qmakeSpec == "win32-msvc2012" || qmakeSpec.startsWith("win32-g++");
2939          if (dictionary[ "SHARED" ] == "no") {
2940 -            cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl
2941 -                 << endl;
2942 -            available = false;
2943 +           // cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl
2944 +           //      << endl;
2945 +          //  available = false;
2946          }
2947      } else if (part == "AUDIO_BACKEND") {
2948          available = true;
This page took 1.648998 seconds and 3 git commands to generate.