]> git.pld-linux.org Git - packages/qt4.git/blame - qt4-wkhtml.patch
- exceptions are used in some parts, rel 44
[packages/qt4.git] / qt4-wkhtml.patch
CommitLineData
3583d8d7
JB
1git 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
3git 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) {
46diff --git a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
47index 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);
61diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
62index 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)
98diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
99index 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;
111diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
112index 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
160diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.h b/src/3rdparty/webkit/Source/WebCore/page/Settings.h
161index 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;
204diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
205index 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
218diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
219index 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
240diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
241index 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 }
289diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
290index 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 }
327diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
328index 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();
361diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
362index 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;
383diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
384index 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) {
397diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
398index 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)
411diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
412index 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 }
565diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
566index 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.
640diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
641index 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
653diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
654index 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;
665diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
666index 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
859diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
860index 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;
912diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
913index 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()
946diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
947index 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
1086diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
1087index 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();
1106diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
1107index 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
1123diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
1124index 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)
1156diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
1157index 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
1169diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
1170index 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");
1182diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
1183index 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,
1217diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
1218index 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());
1253diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
1254index 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.
1476diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
1477index 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 {
1548diff --git a/src/gui/painting/qprintengine.h b/src/gui/painting/qprintengine.h
1549index 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;
1571diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
1572index 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");
2345diff --git a/src/gui/painting/qprintengine_pdf_p.h b/src/gui/painting/qprintengine_pdf_p.h
2346index 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;
2469diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
2470index 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
2513diff --git a/src/gui/painting/qprinter.h b/src/gui/painting/qprinter.h
2514index 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
2527diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
2528index 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);
2548diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp
2549index 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>"
2918diff --git a/src/svg/qsvggenerator.h b/src/svg/qsvggenerator.h
2919index 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;
2932diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
2933index 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 0.390742 seconds and 4 git commands to generate.