1 git clone git://gitorious.org/~antialize/qt/antializes-qt.git, then checkout 4.8.4
2 # check 4.8.4 commit ID on git://gitorious.org/qt/qt.git
3 git diff 96311def2466dd44de64d77a1c815b22fbf68f71
4 # parts related to static QtWebkit build are disabled
6 #diff --git a/configure b/configure
7 #index e3d464b..114933e 100755
10 #@@ -7749,12 +7749,12 @@ if [ "$CFG_GUI" = "no" ]; then
14 #-if [ "$CFG_SHARED" = "no" ]; then
16 #- echo "WARNING: Using static linking will disable the WebKit module."
18 #- canBuildWebKit="no"
20 #+#if [ "$CFG_SHARED" = "no" ]; then
22 #+ # echo "WARNING: Using static linking will disable the WebKit module."
24 #+ # canBuildWebKit="no"
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
38 #+ !isEmpty(INSTALL_LIBS): target.path = $$INSTALL_LIBS
39 #+ else: target.path = $$[QT_INSTALL_LIBS]
43 # lessThan(QT_GCC_MAJOR_VERSION, 5) {
44 # # GCC 4.5 and before
45 # lessThan(QT_GCC_MINOR_VERSION, 6) {
46 diff --git a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
47 index ef72fb7..54ff69c 100644
48 --- a/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
49 +++ b/src/3rdparty/webkit/Source/WebCore/page/FrameView.cpp
50 @@ -1080,7 +1080,9 @@ void FrameView::adjustMediaTypeForPrinting(bool printing)
52 if (m_mediaTypeWhenNotPrinting.isNull())
53 m_mediaTypeWhenNotPrinting = mediaType();
54 - setMediaType("print");
56 + String mediaType = (m_frame && m_frame->settings())?m_frame->settings()->printingMediaType():"print";
57 + setMediaType(mediaType);
59 if (!m_mediaTypeWhenNotPrinting.isNull())
60 setMediaType(m_mediaTypeWhenNotPrinting);
61 diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
62 index 660ad11..8dffd52 100644
63 --- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
64 +++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.cpp
66 #include "FrameView.h"
67 #include "RenderLayer.h"
68 #include "RenderView.h"
69 +#include "Settings.h"
70 #include <wtf/text/StringConcatenate.h>
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.
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;
84 + if (maximumShrinkFactor < minimumShrinkFactor || minimumShrinkFactor <= 0.0f) {
85 + minimumShrinkFactor = printingMinimumShrinkFactor;
86 + maximumShrinkFactor = printingMaximumShrinkFactor;
89 + float minLayoutWidth = width * minimumShrinkFactor;
90 + float minLayoutHeight = height * minimumShrinkFactor;
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);
97 float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize)
98 diff --git a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
99 index aadff47..19f378e 100644
100 --- a/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
101 +++ b/src/3rdparty/webkit/Source/WebCore/page/PrintContext.h
102 @@ -83,6 +83,8 @@ public:
103 // (pageSizeInPixels.height() + 1) * number-of-pages - 1
104 static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels);
107 + const Vector<IntRect> & getPageRects() const {return m_pageRects;}
110 Vector<IntRect> m_pageRects;
111 diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
112 index 2025bd0..5414246 100644
113 --- a/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
114 +++ b/src/3rdparty/webkit/Source/WebCore/page/Settings.cpp
115 @@ -87,6 +87,7 @@ static EditingBehaviorType editingBehaviorTypeForPlatform()
117 Settings::Settings(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)
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;
136 +void Settings::setPrintingMediaType(const String& type)
138 + m_printingMediaType = type;
141 void Settings::setOfflineWebApplicationCacheEnabled(bool enabled)
143 m_offlineWebApplicationCacheEnabled = enabled;
144 @@ -744,4 +752,15 @@ void Settings::setTiledBackingStoreEnabled(bool enabled)
148 +void Settings::setPrintingMinimumShrinkFactor(float printingMinimumShrinkFactor)
150 + m_printingMinimumShrinkFactor = printingMinimumShrinkFactor;
153 +void Settings::setPrintingMaximumShrinkFactor(float printingMaximumShrinkFactor)
155 + m_printingMaximumShrinkFactor = printingMaximumShrinkFactor;
159 } // namespace WebCore
160 diff --git a/src/3rdparty/webkit/Source/WebCore/page/Settings.h b/src/3rdparty/webkit/Source/WebCore/page/Settings.h
161 index 1d2a138..d827693 100644
162 --- a/src/3rdparty/webkit/Source/WebCore/page/Settings.h
163 +++ b/src/3rdparty/webkit/Source/WebCore/page/Settings.h
164 @@ -258,6 +258,9 @@ namespace WebCore {
165 void setApplicationChromeMode(bool);
166 bool inApplicationChromeMode() const { return m_inApplicationChromeMode; }
168 + void setPrintingMediaType(const String&);
169 + const String& printingMediaType() const { return m_printingMediaType; }
171 void setOfflineWebApplicationCacheEnabled(bool);
172 bool offlineWebApplicationCacheEnabled() const { return m_offlineWebApplicationCacheEnabled; }
174 @@ -349,6 +352,12 @@ namespace WebCore {
176 void setTiledBackingStoreEnabled(bool);
177 bool tiledBackingStoreEnabled() const { return m_tiledBackingStoreEnabled; }
179 + void setPrintingMinimumShrinkFactor(float);
180 + float printingMinimumShrinkFactor() const { return m_printingMinimumShrinkFactor; }
182 + void setPrintingMaximumShrinkFactor(float);
183 + float printingMaximumShrinkFactor() const { return m_printingMaximumShrinkFactor; }
185 void setPaginateDuringLayoutEnabled(bool flag) { m_paginateDuringLayoutEnabled = flag; }
186 bool paginateDuringLayoutEnabled() const { return m_paginateDuringLayoutEnabled; }
187 @@ -419,6 +428,7 @@ namespace WebCore {
188 String m_defaultTextEncodingName;
189 String m_ftpDirectoryTemplatePath;
190 String m_localStorageDatabasePath;
191 + String m_printingMediaType;
192 KURL m_userStyleSheetLocation;
193 AtomicString m_standardFontFamily;
194 AtomicString m_fixedFontFamily;
195 @@ -429,6 +439,8 @@ namespace WebCore {
196 EditableLinkBehavior m_editableLinkBehavior;
197 TextDirectionSubmenuInclusionBehavior m_textDirectionSubmenuInclusionBehavior;
198 double m_passwordEchoDurationInSeconds;
199 + float m_printingMinimumShrinkFactor;
200 + float m_printingMaximumShrinkFactor;
201 int m_minimumFontSize;
202 int m_minimumLogicalFontSize;
203 int m_defaultFontSize;
204 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
205 index c348870..4069687 100644
206 --- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
207 +++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
208 @@ -73,7 +73,8 @@ FontPlatformData::FontPlatformData(const FontDescription& description, const Ato
209 font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing);
210 const bool smallCaps = description.smallCaps();
211 font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase);
212 - font.setStyleStrategy(QFont::ForceIntegerMetrics);
213 + // Commented out to work around webkit bug 93263
214 + //font.setStyleStrategy(QFont::ForceIntegerMetrics);
216 m_data->bold = font.bold();
217 // WebKit allows font size zero but QFont does not. We will return
218 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
219 index 0c8ce9e..5ba54d0 100644
220 --- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
221 +++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/qt/ImageQt.cpp
223 #include "PlatformString.h"
224 #include "StillImageQt.h"
225 #include "qwebsettings.h"
226 +#include "SharedBuffer.h"
230 @@ -234,7 +235,8 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
234 - ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc);
235 + QByteArray a = QByteArray::fromRawData(data()->data(), data()->size());
236 + ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc, &a);
238 ctxt->setCompositeOperation(previousOperator);
240 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
241 index 4db8bd1..0f405cb 100644
242 --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
243 +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/PlatformScreenQt.cpp
244 @@ -53,11 +53,17 @@ static int screenNumber(Widget* w)
246 int screenDepth(Widget* w)
248 + if (QApplication::type() == QApplication::Tty)
251 return QApplication::desktop()->screen(screenNumber(w))->depth();
254 int screenDepthPerComponent(Widget* w)
256 + if (QApplication::type() == QApplication::Tty)
259 int depth = QApplication::desktop()->screen(0)->depth();
261 QWebPageClient* client = w->root()->hostWindow()->platformPageClient();
262 @@ -86,17 +92,26 @@ int screenDepthPerComponent(Widget* w)
264 bool screenIsMonochrome(Widget* w)
266 + if (QApplication::type() == QApplication::Tty)
269 return QApplication::desktop()->screen(screenNumber(w))->colorCount() == 2;
272 FloatRect screenRect(Widget* w)
274 + if (QApplication::type() == QApplication::Tty)
275 + return FloatRect(0,0,800,600);
277 QRect r = QApplication::desktop()->screenGeometry(screenNumber(w));
278 return FloatRect(r.x(), r.y(), r.width(), r.height());
281 FloatRect screenAvailableRect(Widget* w)
283 + if (QApplication::type() == QApplication::Tty)
284 + return FloatRect(0,0,800,600);
286 QRect r = QApplication::desktop()->availableGeometry(screenNumber(w));
287 return FloatRect(r.x(), r.y(), r.width(), r.height());
289 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
290 index f98df88..b1fe30d 100644
291 --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
292 +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/RenderThemeQt.cpp
293 @@ -178,7 +178,13 @@ RenderThemeQt::RenderThemeQt(Page* page)
297 + , m_fallbackStyle(0)
299 + if (QApplication::type() == QApplication::Tty) {
300 + m_buttonFontFamily = "sans-serif";
305 button.setAttribute(Qt::WA_MacSmallSize);
306 QFont defaultButtonFont = QApplication::font(&button);
307 @@ -339,6 +345,9 @@ bool RenderThemeQt::supportsControlTints() const
309 int RenderThemeQt::findFrameLineWidth(QStyle* style) const
311 + if (QApplication::type()==QApplication::Tty)
314 #ifndef QT_NO_LINEEDIT
316 m_lineEdit = new QLineEdit();
317 @@ -445,6 +454,9 @@ Color RenderThemeQt::systemColor(int cssValueId) const
319 int RenderThemeQt::minimumMenuListSize(RenderStyle*) const
321 + if (QApplication::type() == QApplication::Tty)
324 const QFontMetrics &fm = QApplication::fontMetrics();
325 return fm.width(QLatin1Char('x'));
327 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
328 index d648c53..f844d54 100644
329 --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
330 +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/ScreenQt.cpp
331 @@ -54,6 +54,9 @@ static QWidget* qwidgetForPage(const Page* page)
333 FloatRect screenRect(const Page* page)
335 + if (QApplication::type() == QApplication::Tty)
336 + return FloatRect(0,0,800,600);
338 QWidget* qw = qwidgetForPage(page);
341 @@ -68,6 +71,9 @@ FloatRect screenRect(const Page* page)
343 int screenDepth(const Page* page)
345 + if (QApplication::type() == QApplication::Tty)
348 QWidget* qw = qwidgetForPage(page);
351 @@ -77,6 +83,9 @@ int screenDepth(const Page* page)
353 FloatRect usableScreenRect(const Page* page)
355 + if (QApplication::type() == QApplication::Tty)
356 + return FloatRect();
358 QWidget* qw = qwidgetForPage(page);
361 diff --git a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
362 index 5215e66..e033279 100644
363 --- a/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
364 +++ b/src/3rdparty/webkit/Source/WebCore/platform/qt/WidgetQt.cpp
366 #include "QWebPageClient.h"
367 #include "ScrollView.h"
369 +#include <QApplication>
370 #include <QCoreApplication>
372 #include <QPaintEngine>
373 @@ -78,6 +79,9 @@ void Widget::setFocus(bool focused)
374 void Widget::setCursor(const Cursor& cursor)
377 + if (QApplication::type() == QApplication::Tty)
380 ScrollView* view = root();
383 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
384 index 2e92801..1690c2f 100644
385 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
386 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlockLineLayout.cpp
387 @@ -956,7 +956,8 @@ void RenderBlock::layoutRunsAndFloats(bool fullLayout, bool hasInlineChild, Vect
388 repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow());
392 + // table cell pagination is handled in RenderTableSection
393 + if (paginated && !isTableCell()) {
395 adjustLinePositionForPagination(lineBox, adjustment);
397 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
398 index f052ee7..a5afea5 100644
399 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
400 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBox.cpp
401 @@ -804,7 +804,8 @@ void RenderBox::paintRootBoxFillLayers(const PaintInfo& paintInfo)
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);
410 void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
411 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
412 index 73b0801..c34b1c2 100644
413 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
414 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
415 @@ -302,11 +302,20 @@ void RenderTable::layout()
417 bool collapsing = collapseBorders();
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;
433 + totalSectionLogicalHeight += rowHeight;
435 section->recalcOuterBorder();
436 ASSERT(!section->needsLayout());
437 @@ -320,6 +329,30 @@ void RenderTable::layout()
439 m_caption->layoutIfNeeded();
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();
453 + // FIXME: Calculate maximum required height across all cells in first body row
454 + RenderTableCell* firstCell = m_firstBody->primaryCellAt(0, 0);
456 + requiredHeight += firstCell->contentLogicalHeight() + firstCell->paddingTop(false) + firstCell->paddingBottom(false) + vBorderSpacing();
459 + if (requiredHeight > remainingLogicalHeight) {
460 + setPaginationStrut(remainingLogicalHeight);
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
468 @@ -352,12 +385,6 @@ void RenderTable::layout()
469 computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength);
470 computedLogicalHeight = max(0, computedLogicalHeight);
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);
478 if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
479 // Completely empty tables (with no sections or anything) should at least honor specified height
481 @@ -377,6 +404,9 @@ void RenderTable::layout()
483 section->setLogicalLocation(sectionLogicalLeft, logicalHeight());
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);
488 setLogicalHeight(logicalHeight() + section->logicalHeight());
489 section = sectionBelow(section);
491 @@ -503,7 +533,59 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
492 child->paint(info, childPoint.x(), childPoint.y());
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
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());
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
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) {
524 + for(RenderObject* row = section->firstChild(); row; row = row->nextSibling()) {
525 + if (!row->isTableRow()) {
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) {
535 + } else if (row_dy > max_dy) {
542 + repaintedFoot = true;
543 + repaintedFootPoint = IntPoint(childPoint.x(), dy - m_foot->y());
544 + dynamic_cast<RenderObject*>(m_foot)->paint(info, repaintedFootPoint.x(), repaintedFootPoint.y());
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;
562 child->paint(info, childPoint.x(), childPoint.y());
565 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
566 index 7d414a0..6c814b3 100644
567 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
568 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
569 @@ -414,7 +414,7 @@ void RenderTableSection::layout()
570 setNeedsLayout(false);
573 -int RenderTableSection::layoutRows(int toAdd)
574 +int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
577 setNeedsLayoutIsForbidden(true);
578 @@ -496,12 +496,47 @@ int RenderTableSection::layoutRows(int toAdd)
580 LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
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;
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;
595 + for (int r = 0; r < totalRows; ++r) {
596 + int rowLogicalOffset = m_rowPos[r] + pageOffset;
597 + int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(rowLogicalOffset) % pageLogicalHeight;
599 + for (int c = 0; c < nEffCols; c++) {
600 + CellStruct& cs = cellAt(r, c);
601 + RenderTableCell* cell = cs.primaryCell();
603 + if (!cell || cs.inColSpan || cell->row() != r)
606 + int cellRequiredHeight = cell->contentLogicalHeight() + cell->paddingTop(false) + cell->paddingBottom(false);
607 + if (max(logicalRowHeights[r], cellRequiredHeight) > remainingLogicalHeight - footHeight - vspacing) {
608 + pageOffset += remainingLogicalHeight + headHeight;
612 + m_rowPos[r] += pageOffset;
614 + m_rowPos[totalRows] += pageOffset;
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();
627 @@ -513,7 +548,11 @@ int RenderTableSection::layoutRows(int toAdd)
631 - rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
632 + if (cell->rowSpan() == 1) {
633 + rHeight = logicalRowHeights[rindx];
635 + rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
638 // Force percent height children to lay themselves out again.
639 // This will cause these children to grow to fill the cell.
640 diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
641 index db6edc2..9d912a0 100644
642 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
643 +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h
644 @@ -49,7 +49,7 @@ public:
646 void setCellLogicalWidths();
647 int calcRowLogicalHeight();
648 - int layoutRows(int logicalHeight);
649 + int layoutRows(int logicalHeight, int headHeight, int footHeight);
651 RenderTable* table() const { return toRenderTable(parent()); }
653 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
654 index 4b1a758..2ad7f1f 100644
655 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
656 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebelement.h
657 @@ -170,6 +170,7 @@ private:
658 friend class QWebHitTestResult;
659 friend class QWebHitTestResultPrivate;
660 friend class QWebPage;
661 + friend class QWebPrinter;
663 #if defined(WTF_USE_V8) && WTF_USE_V8
664 friend class V8::Bindings::QtWebElementRuntime;
665 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
666 index 5ea7059..b0229ed 100644
667 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
668 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.cpp
669 @@ -216,6 +216,114 @@ static inline ResourceRequestCachePolicy cacheLoadControlToCachePolicy(uint cach
670 return WebCore::UseProtocolCachePolicy;
673 +#ifndef QT_NO_PRINTER
674 +QWebPrinterPrivate::QWebPrinterPrivate(const QWebFrame *f, QPaintDevice *printer, QPainter &p)
675 + : printContext(f->d->frame)
678 + , graphicsContext(&p)
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));
686 + printContext.begin(pageRect.width(), pageRect.height());
687 + float pageHeight = 0;
688 + printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight);
690 + painter.scale(zoomFactorX, zoomFactorY);
691 + printWidth = pageRect.width();
694 +QWebPrinterPrivate::~QWebPrinterPrivate()
696 + printContext.end();
702 + \brief The QWebPrinter controls printing of a \l{QWebFrame::}
708 +QWebPrinter::QWebPrinter(const QWebFrame *frame, QPaintDevice *printer, QPainter &painter)
709 + : d(new QWebPrinterPrivate(frame, printer, painter))
712 +QWebPrinter::~QWebPrinter()
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() .
721 +void QWebPrinter::spoolPage(int i) const
723 + if (i < 1 || i > d->printContext.pageCount())
725 + d->printContext.spoolPage(d->graphicsContext, i - 1, d->printWidth);
729 + Returns the number of pages of the frame when printed.
731 +int QWebPrinter::pageCount() const
733 + return d->printContext.pageCount();
736 +QPair<int, QRectF> QWebPrinter::elementLocation(const QWebElement & e)
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())
742 + d->elementToRenderObject[o->node()] = o;
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();
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();
753 + QRectF r(const_cast<WebCore::RenderObject *>(ro)->absoluteBoundingBoxRect());
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())
762 + else if(c > pageRects[m].maxY())
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));
770 + return QPair<int,QRectF>(-1, QRectF());
774 + Return the painter used for printing.
776 +QPainter * QWebPrinter::painter() {
777 + return &d->painter;
779 +#endif //QT_NO_PRINTER
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
788 - if (!painter.begin(printer))
791 - const qreal zoomFactorX = (qreal)printer->logicalDpiX() / qt_defaultDpi();
792 - const qreal zoomFactorY = (qreal)printer->logicalDpiY() / qt_defaultDpi();
794 - PrintContext printContext(d->frame);
795 - float pageHeight = 0;
797 - QRect qprinterRect = printer->pageRect();
799 - IntRect pageRect(0, 0,
800 - int(qprinterRect.width() / zoomFactorX),
801 - int(qprinterRect.height() / zoomFactorY));
803 - printContext.begin(pageRect.width());
805 - printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight);
807 + painter.begin(printer);
808 + QWebPrinter p(this, printer, painter);
811 if (printer->collateCopies()) {
812 @@ -1469,11 +1560,12 @@ void QWebFrame::print(QPrinter *printer) const
814 if (fromPage == 0 && toPage == 0) {
816 - toPage = printContext.pageCount();
817 + toPage = p.pageCount();
820 fromPage = qMax(1, fromPage);
821 - toPage = qMin(static_cast<int>(printContext.pageCount()), toPage);
822 + toPage = qMin(static_cast<int>(p.pageCount()), toPage);
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
832 - painter.scale(zoomFactorX, zoomFactorY);
833 - GraphicsContext ctx(&painter);
835 for (int i = 0; i < docCopies; ++i) {
838 for (int j = 0; j < pageCopies; ++j) {
839 if (printer->printerState() == QPrinter::Aborted
840 || printer->printerState() == QPrinter::Error) {
841 - printContext.end();
844 - printContext.spoolPage(ctx, page - 1, pageRect.width());
846 if (j < pageCopies - 1)
849 @@ -1518,8 +1605,7 @@ void QWebFrame::print(QPrinter *printer) const
850 if ( i < docCopies - 1)
854 - printContext.end();
857 #endif // QT_NO_PRINTER
859 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
860 index 3c5a28e..99771f8 100644
861 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
862 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe.h
867 +#define __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
869 #include <QtCore/qobject.h>
870 #include <QtCore/qurl.h>
871 #include <QtCore/qvariant.h>
872 @@ -42,6 +44,9 @@ class QPrinter;
875 class QWebNetworkRequest;
876 +#ifndef QT_NO_PRINTER
877 +class QWebPrinterPrivate;
879 class QWebFramePrivate;
881 class QWebHitTestResult;
882 @@ -103,6 +108,20 @@ private:
883 friend class QWebPage;
886 +#ifndef QT_NO_PRINTER
887 +class QWEBKIT_EXPORT QWebPrinter {
889 + QWebPrinter(const QWebFrame * frame, QPaintDevice * printer, QPainter &painter);
891 + void spoolPage(int i) const;
892 + QPainter * painter();
893 + int pageCount() const;
894 + QPair<int, QRectF> elementLocation(const QWebElement & e);
896 + QWebPrinterPrivate * d;
900 class QWEBKIT_EXPORT QWebFrame : public QObject {
902 Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false)
903 @@ -228,6 +247,8 @@ private:
904 friend class QWebPage;
905 friend class QWebPagePrivate;
906 friend class QWebFramePrivate;
907 + friend class QWebPrinterPrivate;
908 + friend class QWebPrinter;
909 friend class DumpRenderTreeSupportQt;
910 friend class WebCore::WidgetPrivate;
911 friend class WebCore::FrameLoaderClientQt;
912 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
913 index 4108972..3698eed 100644
914 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
915 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebframe_p.h
917 #include "wtf/RefPtr.h"
919 #include "ViewportArguments.h"
920 +#include <qpainter.h>
921 +#include "PrintContext.h"
922 +#include "GraphicsContext.h"
924 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
925 #include "texmap/TextureMapper.h"
926 @@ -69,6 +72,19 @@ public:
930 +class QWebPrinterPrivate {
932 + WebCore::PrintContext printContext;
933 + QPainter & painter;
934 + const QWebFrame * frame;
935 + WebCore::GraphicsContext graphicsContext;
937 + QHash<const WebCore::Node*, const WebCore::RenderObject *> elementToRenderObject;
939 + QWebPrinterPrivate(const QWebFrame * frame, QPaintDevice *printer, QPainter &p);
940 + ~QWebPrinterPrivate();
943 class QWebFramePrivate {
946 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
947 index c1ef92e..dc4de39 100644
948 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
949 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.cpp
950 @@ -75,8 +75,11 @@ public:
951 QUrl userStyleSheetLocation;
952 QString defaultTextEncoding;
953 QString localStoragePath;
954 + QString printingMediaType;
955 QString offlineWebApplicationCachePath;
956 qint64 offlineStorageDefaultQuota;
957 + qreal printingMinimumShrinkFactor;
958 + qreal printingMaximumShrinkFactor;
961 WebCore::Settings* settings;
962 @@ -229,9 +232,18 @@ void QWebSettingsPrivate::apply()
963 QString encoding = !defaultTextEncoding.isEmpty() ? defaultTextEncoding: global->defaultTextEncoding;
964 settings->setDefaultTextEncodingName(encoding);
966 + QString type = !printingMediaType.isEmpty() ? printingMediaType : global->printingMediaType;
967 + settings->setPrintingMediaType(type.isEmpty() ? "print" : type);
969 QString storagePath = !localStoragePath.isEmpty() ? localStoragePath : global->localStoragePath;
970 settings->setLocalStorageDatabasePath(storagePath);
972 + float minimumShrinkFactor = printingMinimumShrinkFactor > 0.0f ? printingMinimumShrinkFactor : global->printingMinimumShrinkFactor;
973 + settings->setPrintingMinimumShrinkFactor(minimumShrinkFactor);
975 + float maximumShrinkFactor = printingMaximumShrinkFactor > 0.0f ? printingMaximumShrinkFactor : global->printingMaximumShrinkFactor;
976 + settings->setPrintingMaximumShrinkFactor(maximumShrinkFactor);
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;
990 @@ -527,6 +541,8 @@ QWebSettings::QWebSettings()
991 QWebSettings::QWebSettings(WebCore::Settings* settings)
992 : d(new QWebSettingsPrivate(settings))
994 + d->printingMinimumShrinkFactor = 0.0f;
995 + d->printingMaximumShrinkFactor = 0.0f;
996 d->settings = settings;
998 allSettings()->append(d);
999 @@ -635,6 +651,86 @@ QString QWebSettings::defaultTextEncoding() const
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.
1008 + \sa printingMediaType()
1010 +void QWebSettings::setPrintingMediaType(const QString& type)
1012 + d->printingMediaType = type;
1018 + Returns the media type used when printing or QString() if the
1019 + default value is used.
1021 + \sa setPrintingMediaType()
1023 +QString QWebSettings::printingMediaType() const
1025 + return d->printingMediaType;
1030 + Specifies minimum shrink fator allowed for printing. If set to 0 a
1031 + default value is used.
1033 + When printing, content will be shrunk to reduce page usage, it
1034 + will reduced by a factor between printingMinimumShrinkFactor and
1035 + printingMaximumShrinkFactor.
1037 + \sa printingMinimumShrinkFactor()
1038 + \sa setPrintingMaximumShrinkFactor()
1039 + \sa printingMaximumShrinkFactor()
1041 +void QWebSettings::setPrintingMinimumShrinkFactor(qreal printingMinimumShrinkFactor)
1043 + d->printingMinimumShrinkFactor = printingMinimumShrinkFactor;
1049 + returns the minimum shrink factor used for printing.
1051 + \sa setPrintingMinimumShrinkFactor()
1053 +qreal QWebSettings::printingMinimumShrinkFactor() const
1055 + return d->printingMinimumShrinkFactor;
1060 + Specifies maximum shrink fator allowed for printing. If set to 0 a
1061 + default value is used.
1063 + \sa setPrintingMinimumShrinkFactor()
1065 +void QWebSettings::setPrintingMaximumShrinkFactor(qreal printingMaximumShrinkFactor)
1067 + d->printingMaximumShrinkFactor = printingMaximumShrinkFactor;
1073 + returns the maximum shrink factor used for printing.
1075 + \sa setPrintingMinimumShrinkFactor()
1077 +qreal QWebSettings::printingMaximumShrinkFactor() const
1079 + return d->printingMaximumShrinkFactor;
1083 Sets the path of the icon database to \a path. The icon database is used
1084 to store "favicons" associated with web sites.
1086 diff --git a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
1087 index 008035b..bb134a3 100644
1088 --- a/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
1089 +++ b/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebsettings.h
1090 @@ -116,6 +116,15 @@ public:
1091 void setDefaultTextEncoding(const QString &encoding);
1092 QString defaultTextEncoding() const;
1094 + void setPrintingMediaType(const QString &type);
1095 + QString printingMediaType() const;
1097 + void setPrintingMinimumShrinkFactor(qreal printingMinimumShrinkFactor);
1098 + qreal printingMinimumShrinkFactor() const;
1100 + void setPrintingMaximumShrinkFactor(qreal printingMaximimShrinkFactor);
1101 + qreal printingMaximumShrinkFactor() const;
1103 static void setIconDatabasePath(const QString &location);
1104 static QString iconDatabasePath();
1105 static void clearIconDatabase();
1106 diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
1107 index 3fc65d3..6657879 100644
1108 --- a/src/gui/image/qpixmap.cpp
1109 +++ b/src/gui/image/qpixmap.cpp
1110 @@ -134,12 +134,6 @@ extern QApplication::Type qt_appType;
1112 void QPixmap::init(int w, int h, int type)
1114 - if (qt_appType == QApplication::Tty) {
1115 - qWarning("QPixmap: Cannot create a QPixmap when no GUI is being used");
1120 if ((w > 0 && h > 0) || type == QPixmapData::BitmapType)
1121 data = QPixmapData::create(w, h, (QPixmapData::PixelType) type);
1123 diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
1124 index 5950c5d..36303a0 100644
1125 --- a/src/gui/image/qpixmap_raster.cpp
1126 +++ b/src/gui/image/qpixmap_raster.cpp
1128 #include "qnativeimage_p.h"
1129 #include "qimage_p.h"
1130 #include "qpaintengine.h"
1131 +#include "kernel/qapplication_p.h"
1133 #include "qbitmap.h"
1135 @@ -115,8 +116,10 @@ void QRasterPixmapData::resize(int width, int height)
1137 if (pixelType() == BitmapType)
1138 format = QImage::Format_MonoLSB;
1140 + else if (qt_is_gui_used)
1141 format = QNativeImage::systemFormat();
1143 + format = QImage::Format_RGB32;
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;
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;
1155 #if !defined(QT_HAVE_NEON) && !defined(QT_ALWAYS_HAVE_SSE2)
1156 diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
1157 index 9582abf..ebaea4b 100644
1158 --- a/src/gui/kernel/qapplication_x11.cpp
1159 +++ b/src/gui/kernel/qapplication_x11.cpp
1160 @@ -2280,6 +2280,8 @@ void qt_init(QApplicationPrivate *priv, int,
1161 QSegfaultHandler::initialize(priv->argv, priv->argc);
1163 QCursorData::initialize();
1164 + } else if (!QApplicationPrivate::graphics_system_name.isNull()) {
1165 + QApplicationPrivate::graphics_system = QGraphicsSystemFactory::create(QApplicationPrivate::graphics_system_name);
1167 QFont::initialize();
1169 diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
1170 index d8aefb6..37106f7 100644
1171 --- a/src/gui/kernel/qguiplatformplugin.cpp
1172 +++ b/src/gui/kernel/qguiplatformplugin.cpp
1173 @@ -85,7 +85,7 @@ QGuiPlatformPlugin *qt_guiPlatformPlugin()
1175 QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN"));
1177 - if (key.isEmpty()) {
1178 + if (QApplication::type() != QApplication::Tty && key.isEmpty()) {
1179 switch(X11->desktopEnvironment) {
1181 key = QString::fromLatin1("kde");
1182 diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
1183 index cd7075e..74508b3 100644
1184 --- a/src/gui/painting/qpaintengine.h
1185 +++ b/src/gui/painting/qpaintengine.h
1186 @@ -162,6 +162,19 @@ public:
1187 virtual void drawRects(const QRect *rects, int rectCount);
1188 virtual void drawRects(const QRectF *rects, int rectCount);
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);
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);
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);
1203 virtual void drawLines(const QLine *lines, int lineCount);
1204 virtual void drawLines(const QLineF *lines, int lineCount);
1206 @@ -177,6 +190,10 @@ public:
1207 virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
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) {
1212 + drawPixmap(r,pm,sr);
1214 virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
1215 virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
1216 virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
1217 diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
1218 index 10ca689..d690761 100644
1219 --- a/src/gui/painting/qpaintengine_raster.cpp
1220 +++ b/src/gui/painting/qpaintengine_raster.cpp
1221 @@ -2243,11 +2243,11 @@ namespace {
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)
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();
1235 @@ -2255,6 +2255,17 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
1237 Q_D(QRasterPaintEngine);
1238 QRasterPaintEngineState *s = state();
1242 + if (s->matrix.isAffine()) {
1243 + img = _img.copy(sr.toRect()).scaled(
1244 + s->matrix.mapRect(r).size().toSize(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1250 int sr_l = qFloor(sr.left());
1251 int sr_r = qCeil(sr.right()) - 1;
1252 int sr_t = qFloor(sr.top());
1253 diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
1254 index 30f986d..7836b5a 100644
1255 --- a/src/gui/painting/qpainter.cpp
1256 +++ b/src/gui/painting/qpainter.cpp
1257 @@ -5393,7 +5393,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
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)
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();
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);
1275 @@ -7254,6 +7254,200 @@ void QPainter::fillRect(const QRectF &r, const QColor &color)
1281 + \fn void QPainter::addAnchor(int x, int y, int w, int h, const QString &name);
1285 + Add an anchor to the current page at the rect specified by \a x, \a y, \a w and \a h
1288 + Note that for output formats not supporting links, currently all other then PDF,
1289 + this call has no effect.
1297 + \fn void QPainter::addAnchor(const QRect &r, const QString &name);
1301 + Add an anchor to the current page at the rect specified by \a r named \a name.
1303 + Note that for output formats not supporting links, currently all other then PDF,
1304 + this call has no effect.
1312 + \fn void addAnchor(const QRectF &r, const QString &name);
1316 + Add an anchor to the current page at the rect specified by \a r named \a name.
1318 + Note that for output formats not supporting links, currently all other then PDF,
1319 + this call has no effect.
1325 +void QPainter::addAnchor(const QRectF &r, const QString &name)
1329 + qWarning("QPainter::addAnchor: Painter not active");
1332 + d->engine->addAnchor(worldTransform().mapRect(r), name);
1336 + \fn void QPainter::addLink(int x, int y, int w, int h, const QString &anchor);
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.
1343 + Note that for output formats not supporting links, currently all other then PDF,
1344 + this call has no effect.
1352 + \fn void QPainter::addLink(const QRect &r, const QString &anchor);
1356 + Add a link to the current page at the rect specified by \a r
1357 + linking to the anchor named \a anchor.
1359 + Note that for output formats not supporting links, currently all other then PDF,
1360 + this call has no effect.
1368 + \fn void QPainter::addLink(const QRectF &r, const QString &anchor);
1372 + Add a link to the current page at the rect specified by \a r
1373 + linking to the anchor named \a anchor.
1375 + Note that for output formats not supporting links, currently all other then PDF,
1376 + this call has no effect.
1382 +void QPainter::addLink(const QRectF &r, const QString &anchor)
1386 + qWarning("QPainter::addLink: Painter not active");
1390 + d->engine->addLink(worldTransform().mapRect(r), anchor);
1395 + \fn void QPainter::addHyperlink(int x, int y, int w, int h, const QUrl &url);
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.
1402 + Note that for output formats not supporting links, currently all other then PDF,
1403 + this call has no effect.
1409 + \fn void QPainter::addHyperlink(const QRect &r, const QUrl &url);
1413 + Add a link to the current page at the rect specified by \a r
1414 + linking to \a url.
1416 + Note that for output formats not supporting links, currently all other then PDF,
1417 + this call has no effect.
1423 + \fn void QPainter::addHyperlink(const QRectF &r, const QUrl &url);
1427 + Add a link to the current page at the rect specified by \a r
1428 + linking to \a url.
1430 + Note that for output formats not supporting links, currently all other then PDF,
1431 + this call has no effect.
1435 +void QPainter::addHyperlink(const QRectF &r, const QUrl &url)
1439 + qWarning("QPainter::addHyperlink: Painter not active");
1442 + d->engine->addHyperlink(worldTransform().mapRect(r), url);
1445 +void QPainter::addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength) {
1448 + qWarning("QPainter::addTextField: Painter not active");
1451 + d->engine->addTextField(worldTransform().mapRect(r), text, name, multiLine, password, readOnly, maxLength);
1454 +void QPainter::addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) {
1457 + qWarning("QPainter::addCheckBox: Painter not active");
1460 + d->engine->addCheckBox(worldTransform().mapRect(r), checked, name, readOnly);
1464 +void QPainter::addRadioButton(const QRectF &r, const QString & group, bool checked, const QString &name, bool readOnly) {
1467 + qWarning("QPainter::addRadioButton: Painter not active");
1470 + d->engine->addRadioButton(worldTransform().mapRect(r), group, checked, name, readOnly);
1474 Sets the given render \a hint on the painter if \a on is true;
1475 otherwise clears the render hint.
1476 diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
1477 index f0312e5..d853a9b 100644
1478 --- a/src/gui/painting/qpainter.h
1479 +++ b/src/gui/painting/qpainter.h
1480 @@ -364,7 +364,7 @@ public:
1481 inline void drawPicture(const QPoint &p, const QPicture &picture);
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);
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);
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);
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);;
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);
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));
1516 +inline void QPainter::addAnchor(int x, int y, int w, int h, const QString &name)
1518 + addAnchor(QRectF(x, y, w, h), name);
1521 +inline void QPainter::addAnchor(const QRect &r, const QString &name)
1523 + addAnchor(QRectF(r), name);
1526 +inline void QPainter::addLink(int x, int y, int w, int h, const QString &anchor)
1528 + addLink(QRectF(x, y, w, h), anchor);
1531 +inline void QPainter::addLink(const QRect &r, const QString &anchor)
1533 + addLink(QRectF(r), anchor);
1536 +inline void QPainter::addHyperlink(int x, int y, int w, int h, const QUrl &url)
1538 + addHyperlink(QRectF(x, y, w, h), url);
1541 +inline void QPainter::addHyperlink(const QRect &r, const QUrl &url)
1543 + addHyperlink(QRectF(r), url);
1546 inline void QPainter::setBrushOrigin(int x, int y)
1548 diff --git a/src/gui/painting/qprintengine.h b/src/gui/painting/qprintengine.h
1549 index 83bbf96..809b51a 100644
1550 --- a/src/gui/painting/qprintengine.h
1551 +++ b/src/gui/painting/qprintengine.h
1552 @@ -90,6 +90,9 @@ public:
1553 PPK_SupportsMultipleCopies,
1554 PPK_PaperSize = PPK_PageSize,
1556 + PPK_UseCompression,
1559 PPK_CustomBase = 0xff00
1562 @@ -97,6 +100,8 @@ public:
1563 virtual QVariant property(PrintEnginePropertyKey key) const = 0;
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;
1570 virtual int metric(QPaintDevice::PaintDeviceMetric) const = 0;
1571 diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
1572 index 239a94f..36eec2e 100644
1573 --- a/src/gui/painting/qprintengine_pdf.cpp
1574 +++ b/src/gui/painting/qprintengine_pdf.cpp
1576 #include <qimagewriter.h>
1577 #include <qbuffer.h>
1578 #include <qdatetime.h>
1579 +#include <QCryptographicHash>
1581 #ifndef QT_NO_PRINTER
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;
1587 -#ifdef QT_NO_COMPRESS
1588 -static const bool do_compress = false;
1590 -static const bool do_compress = true;
1593 QPdfPage::QPdfPage()
1594 : QPdf::ByteStream(true) // Enable file backing
1596 @@ -109,6 +104,30 @@ inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()
1600 +void QPdfEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) {
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();
1609 + QPdfBaseEngine::setProperty(key, value);
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;
1621 + return QPdfBaseEngine::property(key);
1624 QPdfEngine::QPdfEngine(QPrinter::PrinterMode m)
1625 : QPdfBaseEngine(*new QPdfEnginePrivate(m), qt_pdf_decide_features())
1627 @@ -156,6 +175,59 @@ bool QPdfEngine::begin(QPaintDevice *pdev)
1628 bool QPdfEngine::end()
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());
1641 + d->xprintf(">>\n");
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);
1652 + if (d->formFields.size()) {
1653 + uint font = d->addXrefEntry(-1);
1654 + d->xprintf("<</Type/Font/Name/Helv/BaseFont/Helvetica/Subtype/Type1>>\n"
1656 + d->addXrefEntry(d->formFieldList);
1657 + d->xprintf("<</Fields[");
1658 + foreach(const uint & i, d->formFields)
1659 + d->xprintf("%d 0 R ",i);
1661 + "/DR<</Font<</Helv %d 0 R>>>>\n"
1662 + "/DA(/Helv 0 Tf 0 g)\n"
1664 + "endobj\n", font);
1667 + d->catalog = d->addXrefEntry(-1);
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);
1675 + if (d->formFields.size())
1676 + d->xprintf("/AcroForm %d 0 R\n", d->formFieldList);
1678 + if (d->anchors.size())
1679 + d->xprintf("/Dests %d 0 R\n", dests);
1686 d->stream->unsetDevice();
1687 @@ -165,8 +237,83 @@ bool QPdfEngine::end()
1691 +void QPdfEngine::addCheckBox(const QRectF &r, bool checked, const QString &name, bool readOnly) {
1693 + uint obj = d->addXrefEntry(-1);
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();
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));
1708 + "/Subtype/Widget\n"
1709 + "/P %d 0 R\n", d->pages.back());
1711 + d->xprintf("/AS /Yes\n");
1712 + if (!name.isEmpty()) {
1714 + d->printString(name);
1717 + d->xprintf("/Ff %d\n"
1720 + (readOnly?1:0)<<0);
1721 + d->currentPage->annotations.push_back(obj);
1722 + d->formFields.push_back(obj);
1725 +void QPdfEngine::addTextField(const QRectF &r, const QString &text, const QString &name, bool multiLine, bool password, bool readOnly, int maxLength)
1728 + uint obj = d->addXrefEntry(-1);
1730 + QRectF rr = d->pageMatrix().mapRect(r);
1731 + if (d->formFieldList == -1) d->formFieldList = d->requestObject();
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));
1743 + "/Subtype/Widget\n"
1744 + "/P %d 0 R\n", d->pages.back());
1745 + if (!text.isEmpty()) {
1747 + d->printString(text);
1750 + if (!name.isEmpty()) {
1752 + d->printString(name);
1755 + if (maxLength >= 0)
1756 + d->xprintf("/MaxLen %d\n",maxLength);
1757 + d->xprintf("/DA(/Helv 12 Tf 0 g)\n"
1761 + (readOnly?1:0)<<0 | (password?1:0)<<13 | (multiLine?1:0)<<12
1763 + d->currentPage->annotations.push_back(obj);
1764 + d->formFields.push_back(obj);
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)
1770 if (sr.isEmpty() || rectangle.isEmpty() || pixmap.isNull())
1772 @@ -176,22 +323,35 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con
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;
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);
1787 + bool useScaled=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();
1797 *d->currentPage << "q\n/GSa gs\n";
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));
1803 // set current pen as d->brush
1804 d->brush = d->pen.brush();
1807 - d->currentPage->streamImage(image.width(), image.height(), object);
1808 + d->currentPage->streamImage(width, height, object);
1809 *d->currentPage << "Q\n";
1812 @@ -301,18 +461,68 @@ QPdfEnginePrivate::QPdfEnginePrivate(QPrinter::PrinterMode m)
1813 : QPdfBaseEnginePrivate(m)
1817 + doCompress = true;
1819 + imageQuality = 94;
1820 stream = new QDataStream;
1821 pageOrder = QPrinter::FirstPageFirst;
1822 orientation = QPrinter::Portrait;
1823 + outlineRoot = NULL;
1824 + outlineCurrent = NULL;
1828 QPdfEnginePrivate::~QPdfEnginePrivate()
1831 + delete outlineRoot;
1835 +void QPdfEnginePrivate::printAnchor(const QString &name) {
1836 + QByteArray a = name.toUtf8();
1837 + if (a.size() >= 127)
1838 + a = QCryptographicHash::hash(a,QCryptographicHash::Sha1);
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 == '_')
1850 + xprintf("#%02x", c);
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);
1863 + " /Parent %d 0 R\n"
1864 + " /Dest ", i->parent->obj);
1865 + printAnchor(i->anchor);
1866 + xprintf("\n /Count 0\n");
1868 + xprintf(" /Next %d 0 R\n", i->next->obj);
1870 + xprintf(" /Prev %d 0 R\n", i->prev->obj);
1871 + if (i->firstChild)
1872 + xprintf(" /First %d 0 R\n", i->firstChild->obj);
1874 + xprintf(" /Last %d 0 R\n", i->lastChild->obj);
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,
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);
1900 + for (int x = 0; x < w; ++x) {
1901 + *(data++) = qRed(*rgb);
1902 + *(data++) = qGreen(*rgb);
1903 + *(data++) = qBlue(*rgb);
1910 +#include <iostream>
1912 +class jpg_header_reader {
1914 + const QByteArray * data;
1917 + class jpeg_exception {};
1919 + unsigned char next() {
1920 + if (index == data->size()) throw jpeg_exception();
1921 + return data->data()[index++];
1925 + int l = (next() << 8) + next();
1926 + if (l < 2) throw jpeg_exception();
1927 + for (int i=2; i < l; ++i) next();
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();
1941 + bool read(const QByteArray * d) {
1945 + if (next() != 0xFF) throw jpeg_exception();
1946 + unsigned char marker = next();
1947 + if (marker != 0xD8) throw jpeg_exception();
1950 + while (marker != 0xFF) marker=next();
1951 + while (marker == 0xFF) marker=next();
1976 + } catch(jpeg_exception) {
1982 + int precision, height, width, components;
1989 * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
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)
1996 @@ -564,65 +876,97 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
1998 object = writeImage(data, w, h, d, 0, 0);
2000 - QByteArray softMaskData;
2002 QByteArray imageData;
2003 - bool hasAlpha = false;
2004 - bool hasMask = false;
2006 + uLongf target=1024*1024*1024;
2010 + d = (colorMode == QPrinter::GrayScale) ? 8 : 32;
2012 if (QImageWriter::supportedImageFormats().contains("jpeg") && colorMode != QPrinter::GrayScale) {
2013 - QBuffer buffer(&imageData);
2014 + QByteArray imageData2;
2016 + QBuffer buffer(&imageData2);
2017 QImageWriter writer(&buffer, "jpeg");
2018 - writer.setQuality(94);
2019 + writer.setQuality(imageQuality);
2020 writer.write(image);
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);
2031 - hasMask |= (alpha < 255);
2032 - hasAlpha |= (alpha != 0 && alpha != 255);
2037 + if ((uLongf)imageData2.size() < target) {
2038 + imageData=imageData2;
2039 + target = imageData2.size();
2044 - imageData.resize(colorMode == QPrinter::GrayScale ? w * h : 3 * w * h);
2045 - uchar *data = (uchar *)imageData.data();
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;
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;
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();
2093 + w = noneScaled->width();
2094 + h = noneScaled->height();
2096 + if (useScaled) *useScaled = (uns?false:true);
2097 + QByteArray softMaskData;
2098 + bool hasAlpha = false;
2099 + bool hasMask = false;
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);
2111 - hasMask |= (alpha < 255);
2112 - hasAlpha |= (alpha != 0 && alpha != 255);
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);
2122 - hasMask |= (alpha < 255);
2123 - hasAlpha |= (alpha != 0 && alpha != 255);
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);
2130 + hasMask |= (alpha < 255);
2131 + hasAlpha |= (alpha != 0 && alpha != 255);
2135 - if (format == QImage::Format_RGB32)
2136 - hasAlpha = hasMask = false;
2140 int softMaskObject = 0;
2142 @@ -644,7 +988,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
2144 maskObject = writeImage(mask, w, h, 1, 0, 0);
2146 - object = writeImage(imageData, w, h, colorMode == QPrinter::GrayScale ? 8 : 32,
2147 + object = writeImage(imageData, w, h, d,
2148 maskObject, softMaskObject, dct);
2150 imageCache.insert(serial_no, object);
2151 @@ -754,7 +1098,7 @@ void QPdfEnginePrivate::xprintf(const char* fmt, ...)
2152 int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
2154 #ifndef QT_NO_COMPRESS
2155 - if (do_compress) {
2157 int size = QPdfPage::chunkSize();
2160 @@ -828,7 +1172,7 @@ int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
2161 int QPdfEnginePrivate::writeCompressed(const char *src, int len)
2163 #ifndef QT_NO_COMPRESS
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,
2171 len = data.length();
2175 xprintf("/Filter /FlateDecode\n>>\nstream\n");
2177 xprintf(">>\nstream\n");
2178 @@ -904,14 +1248,9 @@ void QPdfEnginePrivate::writeHeader()
2182 - catalog = addXrefEntry(-1);
2183 pageRoot = requestObject();
2185 - "/Type /Catalog\n"
2188 - "endobj\n", pageRoot);
2191 + formFieldList = -1;
2193 graphicsState = addXrefEntry(-1);
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",
2213 + QDateTime fake=now;
2214 + fake.setTimeSpec(Qt::UTC);
2215 + int offset = now.secsTo(fake);
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);
2225 @@ -1035,7 +1383,7 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
2227 "/Length1 " << fontData.size() << "\n"
2228 "/Length " << length_object << "0 R\n";
2231 s << "/Filter /FlateDecode\n";
2234 @@ -1097,6 +1445,101 @@ void QPdfEnginePrivate::writeFonts()
2239 +void QPdfEngine::addHyperlink(const QRectF &r, const QUrl &url)
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();
2250 + for (int j = 0; j < len; j++, k++){
2251 + if (urldata[j] == '(' ||
2252 + urldata[j] == ')' ||
2253 + urldata[j] == '\\'){
2254 + url_esc[k] = '\\';
2257 + url_esc[k] = urldata[j];
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);
2273 +void QPdfEngine::addLink(const QRectF &r, const QString &anchor)
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);
2291 +void QPdfEngine::addAnchor(const QRectF &r, const QString &name)
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;
2306 +void QPdfEngine::beginSectionOutline(const QString &text, const QString &anchor)
2309 + if (d->outlineCurrent == NULL) {
2310 + if (d->outlineRoot)
2311 + delete d->outlineRoot;
2312 + d->outlineCurrent = d->outlineRoot = new QPdfEnginePrivate::OutlineItem(QString(), QString());
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;
2321 + d->outlineCurrent->firstChild = i;
2322 + d->outlineCurrent->lastChild = i;
2323 + d->outlineCurrent = i;
2326 +void QPdfEngine::endSectionOutline()
2329 + if (d->outlineCurrent)
2330 + d->outlineCurrent = d->outlineCurrent->parent;
2333 void QPdfEnginePrivate::writePage()
2336 @@ -1167,7 +1610,7 @@ void QPdfEnginePrivate::writePage()
2337 addXrefEntry(pageStream);
2339 "/Length %d 0 R\n", pageStreamLength); // object number for stream length object
2342 xprintf("/Filter /FlateDecode\n");
2345 diff --git a/src/gui/painting/qprintengine_pdf_p.h b/src/gui/painting/qprintengine_pdf_p.h
2346 index 9b9185a..1586caa 100644
2347 --- a/src/gui/painting/qprintengine_pdf_p.h
2348 +++ b/src/gui/painting/qprintengine_pdf_p.h
2349 @@ -92,7 +92,12 @@ public:
2350 // reimplementations QPaintEngine
2351 bool begin(QPaintDevice *pdev);
2353 - void drawPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr);
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);
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:
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);
2373 // ### unused, should have something for this in QPrintEngine
2374 void setAuthor(const QString &author);
2375 QString author() const;
2377 void setDevice(QIODevice* dev);
2379 + void beginSectionOutline(const QString &text, const QString &anchor);
2380 + void endSectionOutline();
2382 + void setProperty(PrintEnginePropertyKey key, const QVariant &value);
2383 + QVariant property(PrintEnginePropertyKey key) const;
2385 Q_DISABLE_COPY(QPdfEngine)
2387 @@ -124,6 +140,35 @@ class QPdfEnginePrivate : public QPdfBaseEnginePrivate
2389 Q_DECLARE_PUBLIC(QPdfEngine)
2392 + class OutlineItem {
2394 + OutlineItem *parent;
2395 + OutlineItem *next;
2396 + OutlineItem *prev;
2397 + OutlineItem *firstChild;
2398 + OutlineItem *lastChild;
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) {}
2407 + OutlineItem *i = firstChild;
2408 + while(i != NULL) {
2409 + OutlineItem *n = i->next;
2416 + OutlineItem *outlineRoot;
2417 + OutlineItem *outlineCurrent;
2418 + void writeOutlineChildren(OutlineItem *node);
2420 QPdfEnginePrivate(QPrinter::PrinterMode m);
2421 ~QPdfEnginePrivate();
2423 @@ -141,7 +186,9 @@ public:
2427 - int addImage(const QImage &image, bool *bitmap, qint64 serial_no);
2428 + void convertImage(const QImage & image, QByteArray & imageData);
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);
2434 @@ -161,16 +208,25 @@ private:
2436 void embedFont(QFontSubset *font);
2438 + int formFieldList;
2439 + QVector<uint> formFields;
2440 QVector<int> xrefPositions;
2441 QDataStream* stream;
2448 int writeImage(const QByteArray &data, int width, int height, int depth,
2449 int maskObject, int softMaskObject, bool dct = false);
2452 int addXrefEntry(int object, bool printostr = true);
2454 void printString(const QString &string);
2455 + void printAnchor(const QString &name);
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:
2462 // various PDF objects
2463 int pageRoot, catalog, info, graphicsState, patternColorSpace;
2464 + QVector<uint> dests;
2465 + QHash<QString, uint> anchors;
2466 QVector<uint> pages;
2467 QHash<qint64, uint> imageCache;
2468 QHash<QPair<uint, uint>, uint > alphaCache;
2469 diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
2470 index 134447c..2c58619 100644
2471 --- a/src/gui/painting/qprinter.cpp
2472 +++ b/src/gui/painting/qprinter.cpp
2473 @@ -933,6 +933,39 @@ void QPrinter::setOutputFileName(const QString &fileName)
2474 d->addToManualSetList(QPrintEngine::PPK_OutputFileName);
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.
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().
2485 + Note that for output formats not supporting outlines, currently all other then PDF,
2486 + this call has no effect.
2488 + \sa endSectionOutline() QPainter::addAnchor()
2492 +void QPrinter::beginSectionOutline(const QString &name, const QString &anchor)
2495 + d->printEngine->beginSectionOutline(name, anchor);
2499 + End the current section.
2501 + \sa beginSectionOutline()
2505 +void QPrinter::endSectionOutline()
2508 + d->printEngine->endSectionOutline();
2512 Returns the name of the program that sends the print output to the
2513 diff --git a/src/gui/painting/qprinter.h b/src/gui/painting/qprinter.h
2514 index f133a5d..46baf8c 100644
2515 --- a/src/gui/painting/qprinter.h
2516 +++ b/src/gui/painting/qprinter.h
2517 @@ -147,6 +147,9 @@ public:
2518 enum PrinterOption { PrintToFile, PrintSelection, PrintPageRange };
2519 #endif // QT3_SUPPORT
2521 + void beginSectionOutline(const QString &text, const QString &anchor);
2522 + void endSectionOutline();
2524 void setOutputFormat(OutputFormat format);
2525 OutputFormat outputFormat() const;
2527 diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
2528 index 52ce9a7..eddbb80 100644
2529 --- a/src/gui/styles/qstyle.cpp
2530 +++ b/src/gui/styles/qstyle.cpp
2532 #include "qpixmapcache.h"
2533 #include "qstyleoption.h"
2534 #include "private/qstyle_p.h"
2535 +#include "private/qapplication_p.h"
2539 @@ -2229,7 +2230,7 @@ QPalette QStyle::standardPalette() const
2543 - if (QX11Info::appDepth() > 8)
2544 + if (!qt_is_gui_used || QX11Info::appDepth() > 8)
2545 background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey
2547 background = QColor(192, 192, 192);
2548 diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp
2549 index f512992..9ee9096 100644
2550 --- a/src/svg/qsvggenerator.cpp
2551 +++ b/src/svg/qsvggenerator.cpp
2552 @@ -103,6 +103,7 @@ public:
2554 afterFirstUpdate = false;
2560 @@ -129,6 +130,9 @@ public:
2562 QString currentGradientName;
2564 + QString stateString;
2565 + QString oldStateString;
2568 struct _attributes {
2569 QString document_title;
2570 @@ -141,6 +145,18 @@ public:
2571 QString dashPattern, dashOffset;
2572 QString fill, fillOpacity;
2575 + void emitState() {
2576 + if (stateString == oldStateString) return;
2578 + // close old state and start a new one...
2579 + if (afterFirstUpdate)
2580 + *stream << "</g>\n\n";
2582 + *stream << stateString;
2583 + afterFirstUpdate = true;
2584 + oldStateString = stateString;
2588 static inline QPaintEngine::PaintEngineFeatures svgEngineFeatures()
2589 @@ -322,7 +338,7 @@ public:
2593 - void qpenToSvg(const QPen &spen)
2594 + void qpenToSvg(const QPen &spen, QTextStream & s)
2598 @@ -330,7 +346,7 @@ public:
2600 switch (spen.style()) {
2602 - stream() << QLatin1String("stroke=\"none\" ");
2603 + s << QLatin1String("stroke=\"none\" ");
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;
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("\" ");
2618 @@ -368,10 +384,10 @@ public:
2619 d_func()->attributes.dashPattern = dashPattern;
2620 d_func()->attributes.dashOffset = dashOffset;
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("\" ");
2633 @@ -380,50 +396,50 @@ public:
2636 if (spen.widthF() == 0)
2637 - stream() <<"stroke-width=\"1\" ";
2638 + s <<"stroke-width=\"1\" ";
2640 - stream() <<"stroke-width=\"" << spen.widthF() << "\" ";
2641 + s <<"stroke-width=\"" << spen.widthF() << "\" ";
2643 switch (spen.capStyle()) {
2645 - stream() << "stroke-linecap=\"butt\" ";
2646 + s << "stroke-linecap=\"butt\" ";
2649 - stream() << "stroke-linecap=\"square\" ";
2650 + s << "stroke-linecap=\"square\" ";
2653 - stream() << "stroke-linecap=\"round\" ";
2654 + s << "stroke-linecap=\"round\" ";
2657 qWarning("Unhandled cap style");
2659 switch (spen.joinStyle()) {
2661 - stream() << "stroke-linejoin=\"miter\" "
2662 + s << "stroke-linejoin=\"miter\" "
2663 "stroke-miterlimit=\""<<spen.miterLimit()<<"\" ";
2666 - stream() << "stroke-linejoin=\"bevel\" ";
2667 + s << "stroke-linejoin=\"bevel\" ";
2670 - stream() << "stroke-linejoin=\"round\" ";
2671 + s << "stroke-linejoin=\"round\" ";
2673 case Qt::SvgMiterJoin:
2674 - stream() << "stroke-linejoin=\"miter\" "
2675 + s << "stroke-linejoin=\"miter\" "
2676 "stroke-miterlimit=\""<<spen.miterLimit()<<"\" ";
2679 qWarning("Unhandled join style");
2682 - void qbrushToSvg(const QBrush &sbrush)
2683 + void qbrushToSvg(const QBrush &sbrush, QTextStream & s)
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 << "\" "
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(")\" ");
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(")\" ");
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(")\" ");
2717 - stream() << QLatin1String("fill=\"none\" ");
2718 + s << QLatin1String("fill=\"none\" ");
2719 d_func()->attributes.fill = QLatin1String("none");
2720 d_func()->attributes.fillOpacity = QString();
2722 @@ -458,7 +474,7 @@ public:
2726 - void qfontToSvg(const QFont &sfont)
2727 + void qfontToSvg(const QFont &sfont, QTextStream & s)
2729 Q_D(QSvgPaintEngine);
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");
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 << "\" "
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 << "\" "
2747 + void setViewBoxClip(bool clip) {
2748 + Q_D(QSvgPaintEngine);
2752 + bool viewBoxClip() const {
2753 + Q_D(const QSvgPaintEngine);
2759 class QSvgGeneratorPrivate
2760 @@ -808,6 +835,27 @@ int QSvgGenerator::metric(QPaintDevice::PaintDeviceMetric metric) const
2765 + \property QSvgGenerator::resolution
2766 + \brief do not draw objects outside the viewBox
2769 + When specified objects drawn compleatly outsite the viewBox
2770 + are not include in the output SVG.
2775 +bool QSvgGenerator::viewBoxClip() const {
2776 + Q_D(const QSvgGenerator);
2777 + return d->engine->viewBoxClip();
2780 +void QSvgGenerator::setViewBoxClip(bool clip) {
2781 + Q_D(QSvgGenerator);
2782 + d->engine->setViewBoxClip(clip);
2785 /*****************************************************************************
2786 * class QSvgPaintEngine
2788 @@ -908,10 +956,13 @@ void QSvgPaintEngine::drawImage(const QRectF &r, const QImage &image,
2790 Qt::ImageConversionFlag flags)
2792 - //Q_D(QSvgPaintEngine);
2793 + Q_D(QSvgPaintEngine);
2797 + if (d->clip && !d->matrix.mapRect(r).intersects(d->viewBox)) return;
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)
2806 Q_D(QSvgPaintEngine);
2807 - QPaintEngine::DirtyFlags flags = state.state();
2809 - // always stream full gstate, which is not required, but...
2810 - flags |= QPaintEngine::AllDirty;
2812 - // close old state and start a new one...
2813 - if (d->afterFirstUpdate)
2814 - *d->stream << "</g>\n\n";
2816 - *d->stream << "<g ";
2818 - if (flags & QPaintEngine::DirtyBrush) {
2819 - qbrushToSvg(state.brush());
2822 - if (flags & QPaintEngine::DirtyPen) {
2823 - qpenToSvg(state.pen());
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()
2836 - if (flags & QPaintEngine::DirtyFont) {
2837 - qfontToSvg(state.font());
2840 - if (flags & QPaintEngine::DirtyOpacity) {
2841 - if (!qFuzzyIsNull(state.opacity() - 1))
2842 - stream() << "opacity=\""<<state.opacity()<<"\" ";
2845 - *d->stream << '>' << endl;
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);
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()
2861 + qfontToSvg(state.font(), stateStream);
2863 + if (!qFuzzyIsNull(state.opacity() - 1))
2864 + stateStream << "opacity=\""<<state.opacity()<<"\" ";
2866 + stateStream << '>' << endl;
2869 void QSvgPaintEngine::drawPath(const QPainterPath &p)
2871 Q_D(QSvgPaintEngine);
2873 + if (d->clip && !d->matrix.mapRect(p.boundingRect()).intersects(d->viewBox)) return;
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,
2881 Q_ASSERT(pointCount >= 2);
2883 - //Q_D(QSvgPaintEngine);
2884 + Q_D(QSvgPaintEngine);
2886 QPainterPath path(points[0]);
2887 for (int i=1; i<pointCount; ++i)
2888 path.lineTo(points[i]);
2890 + if (d->clip && !d->matrix.mapRect(path.boundingRect()).intersects(d->viewBox)) return;
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)
2901 + QRectF b=painter()->boundingRect( QRectF(pt, QSize()) , Qt::AlignLeft, textItem.text());
2902 + if (!d->matrix.mapRect(b).intersects(d->viewBox)) return;
2906 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
2907 QString s = QString::fromRawData(ti.chars, ti.num_chars);
2909 @@ -1060,7 +1102,7 @@ void QSvgPaintEngine::drawTextItem(const QPointF &pt, const QTextItem &textItem)
2911 "xml:space=\"preserve\" "
2912 "x=\"" << pt.x() << "\" y=\"" << pt.y() << "\" ";
2913 - qfontToSvg(textItem.font());
2914 + qfontToSvg(textItem.font(), *d->stream);
2918 diff --git a/src/svg/qsvggenerator.h b/src/svg/qsvggenerator.h
2919 index 7981f28..2197ad8 100644
2920 --- a/src/svg/qsvggenerator.h
2921 +++ b/src/svg/qsvggenerator.h
2922 @@ -96,6 +96,9 @@ public:
2924 void setResolution(int dpi);
2925 int resolution() const;
2927 + void setViewBoxClip(bool clip);
2928 + bool viewBoxClip() const;
2930 QPaintEngine *paintEngine() const;
2931 int metric(QPaintDevice::PaintDeviceMetric metric) const;
2932 diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
2933 index 4b8000d..6d52696 100644
2934 --- a/tools/configure/configureapp.cpp
2935 +++ b/tools/configure/configureapp.cpp
2936 @@ -2381,9 +2381,9 @@ bool Configure::checkAvailability(const QString &part)
2937 available = qmakeSpec == "win32-msvc2005" || qmakeSpec == "win32-msvc2008" ||
2938 qmakeSpec == "win32-msvc2010" || qmakeSpec == "win32-msvc2012" || qmakeSpec.startsWith("win32-g++");
2939 if (dictionary[ "SHARED" ] == "no") {
2940 - cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl
2942 - available = false;
2943 + // cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl
2945 + // available = false;
2947 } else if (part == "AUDIO_BACKEND") {